<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Franz</title>
    <description>The latest articles on Forem by Franz (@f345345dfg).</description>
    <link>https://forem.com/f345345dfg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3671581%2F5f7f5670-e10e-4728-861f-ef8b79ab638c.png</url>
      <title>Forem: Franz</title>
      <link>https://forem.com/f345345dfg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/f345345dfg"/>
    <language>en</language>
    <item>
      <title>🖥️ The DEC-VAX: The Machine That Changed Computing History</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Wed, 31 Dec 2025 10:16:01 +0000</pubDate>
      <link>https://forem.com/f345345dfg/the-dec-vax-the-machine-that-changed-computing-history-50kf</link>
      <guid>https://forem.com/f345345dfg/the-dec-vax-the-machine-that-changed-computing-history-50kf</guid>
      <description>&lt;h2&gt;
  
  
  🎯 What Was the DEC-VAX?
&lt;/h2&gt;

&lt;p&gt;The DEC-VAX (Virtual Address Extension) was a family of 32-bit minicomputers developed by Digital Equipment Corporation (DEC). The first model, the VAX-11/780, was introduced on October 25, 1977, and shipped starting in 1978. This groundbreaking computer transformed DEC from a $700 million company into a $14 billion powerhouse that seriously challenged even IBM.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 The Birth of a Legend
&lt;/h2&gt;

&lt;p&gt;Gordon Bell, who now works at Microsoft's research division, recognized back in 1972 that the PDP-11 minicomputer wouldn't survive the decade due to its 16-bit address space limitation. In 1975, he started working with a team of engineers to develop a computer with 32-bit addressing that remained compatible with the older PDP-11 minicomputers.&lt;/p&gt;

&lt;p&gt;The first system shipped in 1978 to Carnegie Mellon University in Pittsburgh, followed by CERN in Switzerland and a German Max Planck Institute. 📦&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 Technical Innovation
&lt;/h2&gt;

&lt;p&gt;The VAX-11/780 ran on the VMS operating system (VAX Version 1 contained approximately one million lines of code) and featured innovative capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Built-in error correction (Error Correction and Detection Code; ECC)&lt;/li&gt;
&lt;li&gt;✅ Virtual memory support&lt;/li&gt;
&lt;li&gt;✅ 32-bit architecture breaking the 16-bit barrier&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ⌨️ The VT100 Terminal Legacy
&lt;/h2&gt;

&lt;p&gt;Around 1976, DEC introduced the VT100, an affordable and robust ASCII terminal whose command set remains the de-facto standard for terminal emulation programs today. These terminals, featuring the iconic &lt;strong&gt;gold-colored key&lt;/strong&gt;, were used alongside VAX systems and shaped an entire generation of developers.&lt;/p&gt;

&lt;p&gt;Fun fact: This is why Uniface still uses the "Gold Key" concept! 🔑&lt;/p&gt;

&lt;h2&gt;
  
  
  📈 Market Dominance
&lt;/h2&gt;

&lt;p&gt;By the 1980s, DEC had become the world's second-largest computer manufacturer by revenue, right behind IBM. The company evolved a comprehensive computer family with various subfamilies - advances in chip technology miniaturized the electronics while prices steadily declined.&lt;/p&gt;

&lt;p&gt;DEC's predecessor system, the PDP-11, had already achieved remarkable success with over 600,000 units sold. The VAX family continued this legacy throughout the 1980s. 🌍&lt;/p&gt;

&lt;h2&gt;
  
  
  🔚 The End of an Era
&lt;/h2&gt;

&lt;p&gt;In 1992, the death knell rang for VAX systems when DEC introduced the RISC CPU "21064" (codename: Alpha) - a 64-bit RISC processor, in contrast to the 32-bit CISC architecture of VAX computers. With the retirement of the VAX, a significant chapter in computing history came to an end.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎓 Legacy Impact
&lt;/h2&gt;

&lt;p&gt;The VAX systems influenced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modern operating system design (VMS concepts live on in OpenVMS)&lt;/li&gt;
&lt;li&gt;Terminal standards (VT100 emulation)&lt;/li&gt;
&lt;li&gt;Enterprise computing architecture&lt;/li&gt;
&lt;li&gt;Developer workflows and tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding the VAX era helps us appreciate why certain "legacy" systems work the way they do today! 🏛️&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you worked with VAX systems or encountered their legacy in modern software? Share your stories in the comments! 💬&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This article was created with the assistance of AI to research and compile historical information about DEC-VAX systems.&lt;/p&gt;

</description>
      <category>history</category>
      <category>retrocomputing</category>
      <category>legacy</category>
      <category>hardware</category>
    </item>
    <item>
      <title>🔑 The Gold Key in Uniface - A Relic from the VAX Era</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Wed, 31 Dec 2025 10:07:00 +0000</pubDate>
      <link>https://forem.com/f345345dfg/the-gold-key-in-uniface-a-relic-from-the-vax-era-3mf2</link>
      <guid>https://forem.com/f345345dfg/the-gold-key-in-uniface-a-relic-from-the-vax-era-3mf2</guid>
      <description>&lt;h2&gt;
  
  
  🤔 What is the Gold Key?
&lt;/h2&gt;

&lt;p&gt;The Gold Key is a special key in Uniface that modifies the behavior of subsequently typed characters. This function originates from the original development of Uniface on DEC-VAX machines, whose terminals actually had a &lt;strong&gt;gold-colored or yellow key&lt;/strong&gt; on the keyboard.&lt;/p&gt;

&lt;p&gt;A true piece of computing history! 🖥️✨&lt;/p&gt;

&lt;h2&gt;
  
  
  ⌨️ How to Use the Gold Key Today
&lt;/h2&gt;

&lt;p&gt;On Microsoft Windows, there are several options:&lt;/p&gt;

&lt;h3&gt;
  
  
  Standard Mapping
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Numeric Keypad&lt;/strong&gt;: &lt;code&gt;+&lt;/code&gt; (Plus key on the numpad)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Without Numpad&lt;/strong&gt;: &lt;code&gt;Ctrl + Shift + F1&lt;/code&gt; (press simultaneously)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Applications&lt;/strong&gt;: &lt;code&gt;\&lt;/code&gt; (Backslash)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💡 Practical Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Enter Special Characters 📝
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Gold Key + ;&lt;/code&gt; (semicolon) creates a Gold-semicolon, which serves as a &lt;strong&gt;subfill separator&lt;/strong&gt; in Uniface lists&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Wildcard Search 🔍
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Gold + *&lt;/code&gt; for data query profiles &lt;/p&gt;

&lt;h3&gt;
  
  
  3. Structure Editor Functions ⚡
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Gold + R&lt;/code&gt; = Retrieve&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Gold + ,&lt;/code&gt; = Find Again&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠️ Configuration
&lt;/h2&gt;

&lt;p&gt;Gold Key combinations are defined with &lt;code&gt;^GOLD_BASE_SET&lt;/code&gt; and are available by default in all keyboard translation tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;The Gold Key may seem antiquated at first glance, but it remains an integral part of Uniface operation today. A perfect example of how legacy systems carry their history with them! 🚀&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Do you have more Uniface tips? Share them in the comments! 💬&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This article was created with the assistance of AI to research and compile information about Uniface's Gold Key functionality.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🔌 MySQL Connector in Uniface 10.4: A Developer's Guide</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Tue, 23 Dec 2025 09:02:48 +0000</pubDate>
      <link>https://forem.com/f345345dfg/mysql-connector-in-uniface-104-a-developers-guide-2nmj</link>
      <guid>https://forem.com/f345345dfg/mysql-connector-in-uniface-104-a-developers-guide-2nmj</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This blog post was created with AI assistance and is based on the official Uniface 10.4 documentation for the MySQL connector.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction: Why MySQL Integration Matters for Uniface Developers
&lt;/h2&gt;

&lt;p&gt;If you're working with Uniface 10.4, you're likely maintaining enterprise applications built with this powerful low-code platform. MySQL has become one of the most popular open-source relational database management systems, offering cost-effective data storage and compatibility with modern cloud platforms.&lt;/p&gt;

&lt;p&gt;Whether you're integrating with existing MySQL databases, modernizing legacy systems, or building new functionality, understanding the MySQL connector in Uniface is essential. This guide covers the core features, installation requirements, and practical setup based on official documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the MySQL Connector in Uniface?
&lt;/h2&gt;

&lt;p&gt;The MySQL DBMS connector is a database driver that enables Uniface applications to interact with MySQL database servers. It provides a bridge between Uniface's data model and MySQL's relational database structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Connector Information
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Connector Mnemonic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;MQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQL Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stored Procedures Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Create Table Utility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Load Definitions Utility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Create Scripts Utility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Not Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Understanding the Utilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create Table&lt;/strong&gt;: Allows you to generate MySQL tables directly from Uniface entity definitions in your application model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Definitions&lt;/strong&gt;: Enables reverse engineering—importing existing MySQL table structures into Uniface entities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create Scripts&lt;/strong&gt;: Cannot generate standalone SQL script files (use alternative methods if needed)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Platform and Version Support
&lt;/h2&gt;

&lt;p&gt;The MySQL connector is available for Uniface 10.4 across multiple supported platforms. For the complete list of supported platforms and MySQL versions, consult the official &lt;a href="https://community.rocketsoftware.com/rocket-uniface-product-updates-108/uniface-product-availability-information-18191" rel="noopener noreferrer"&gt;Platform Availability Matrix&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation: The Critical Setup Steps ⚙️
&lt;/h2&gt;

&lt;p&gt;The MySQL connector requires proper configuration to function. Here's what you need to know:&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirement: libmysql.dll
&lt;/h3&gt;

&lt;p&gt;To use the MySQL connector in Uniface, you must copy &lt;strong&gt;libmysql.dll&lt;/strong&gt; from your MySQL installation to your Uniface installation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Essential Step:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Locate libmysql.dll in your MySQL Connector/C installation folder&lt;/li&gt;
&lt;li&gt;Copy it to: &lt;code&gt;&amp;lt;Uniface Installation&amp;gt;\common\bin\&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ⚠️ The 32-bit vs. 64-bit Compatibility Issue
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;This is critical:&lt;/strong&gt; The 32-bit and 64-bit versions of libmysql.dll are &lt;strong&gt;not binary compatible&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You must ensure:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If running &lt;strong&gt;32-bit Uniface&lt;/strong&gt; → copy the &lt;strong&gt;32-bit&lt;/strong&gt; libmysql.dll&lt;/li&gt;
&lt;li&gt;If running &lt;strong&gt;64-bit Uniface&lt;/strong&gt; → copy the &lt;strong&gt;64-bit&lt;/strong&gt; libmysql.dll&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the wrong architecture will result in library loading errors. Always verify which version of Uniface you're running before copying the DLL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring the MySQL Connector in Uniface
&lt;/h2&gt;

&lt;p&gt;Configuration is handled through Uniface's assignment files (&lt;code&gt;.asn&lt;/code&gt; files). The specific syntax and options depend on your Uniface configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Setup Process
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open your assignment file&lt;/strong&gt; in the Uniface IDE or text editor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define the logical database path&lt;/strong&gt; with the MQL mnemonic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure connection parameters&lt;/strong&gt; (hostname, database name, credentials)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test the connection&lt;/strong&gt; before deploying&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For detailed configuration options and parameters specific to your environment, refer to the official Uniface 10.4 documentation on database connector configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Features in Detail
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SQL Support
&lt;/h3&gt;

&lt;p&gt;The MySQL connector supports SQL statements, allowing you to execute queries directly from Uniface applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stored Procedures
&lt;/h3&gt;

&lt;p&gt;MySQL stored procedures are fully supported. You can call existing stored procedures from Uniface and handle their results. This is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complex business logic encapsulated in the database&lt;/li&gt;
&lt;li&gt;Performance-critical operations&lt;/li&gt;
&lt;li&gt;Reusing existing database code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important consideration:&lt;/strong&gt; When working with stored procedures, ensure proper error handling on both the Uniface and MySQL sides.&lt;/p&gt;

&lt;h2&gt;
  
  
  Important Naming Considerations
&lt;/h2&gt;

&lt;p&gt;When using MySQL with Uniface, be aware of naming rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uniface requires uppercase names in the application model definition&lt;/li&gt;
&lt;li&gt;MySQL has reserved words that cannot be used for table or entity names&lt;/li&gt;
&lt;li&gt;Always check the official documentation for reserved words in your MySQL version&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creating Tables from Uniface
&lt;/h3&gt;

&lt;p&gt;Use the Create Table utility when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're building a new application with a database&lt;/li&gt;
&lt;li&gt;You want tables generated automatically from your entity model&lt;/li&gt;
&lt;li&gt;You need consistent naming and structure across entities&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Importing Existing Database Structures
&lt;/h3&gt;

&lt;p&gt;Use Load Definitions when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're integrating with an existing MySQL database&lt;/li&gt;
&lt;li&gt;You need to reverse-engineer database schema into Uniface entities&lt;/li&gt;
&lt;li&gt;You're migrating from another system to Uniface&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Troubleshooting Tips
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Connection Issues
&lt;/h3&gt;

&lt;p&gt;If Uniface cannot load the MySQL connector:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify libmysql.dll is in &lt;code&gt;&amp;lt;Uniface&amp;gt;\common\bin\&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check that the DLL architecture matches your Uniface installation (32-bit or 64-bit)&lt;/li&gt;
&lt;li&gt;Ensure all required files are properly copied&lt;/li&gt;
&lt;li&gt;Verify database connectivity settings in your assignment file&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Library Loading Errors
&lt;/h3&gt;

&lt;p&gt;Common error messages indicate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing libmysql.dll&lt;/li&gt;
&lt;li&gt;Architecture mismatch (32-bit/64-bit)&lt;/li&gt;
&lt;li&gt;Missing dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Naming and Reserved Words
&lt;/h3&gt;

&lt;p&gt;If table creation fails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check for reserved MySQL keywords in your entity names&lt;/li&gt;
&lt;li&gt;Review naming rules in the Uniface documentation for MySQL&lt;/li&gt;
&lt;li&gt;Ensure compliance with both Uniface and MySQL naming conventions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  U_VERSION Mechanism for Locking
&lt;/h2&gt;

&lt;p&gt;The MySQL connector supports the U_VERSION mechanism, which is recommended for improving locking performance in concurrent environments. Consult the Uniface documentation for implementation details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for MySQL Integration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Configuration Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Store connection credentials securely&lt;/li&gt;
&lt;li&gt;Use the Platform Availability Matrix to verify version compatibility&lt;/li&gt;
&lt;li&gt;Test all database operations thoroughly before production deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Development Workflow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Design your data model&lt;/strong&gt; in Uniface first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate tables&lt;/strong&gt; using Create Table utility, or&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Import existing schema&lt;/strong&gt; using Load Definitions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test SQL statements&lt;/strong&gt; and stored procedure calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy with proper configuration&lt;/strong&gt; management&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Using Stored Procedures Effectively
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Keep procedures focused on specific business logic&lt;/li&gt;
&lt;li&gt;Document procedure parameters and expected results&lt;/li&gt;
&lt;li&gt;Handle errors appropriately in both database and Uniface layers&lt;/li&gt;
&lt;li&gt;Test procedures independently before integration&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Referential Integrity
&lt;/h2&gt;

&lt;p&gt;MySQL connector supports referential integrity management. Review the documentation for how to properly implement and maintain referential integrity constraints in your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The MySQL connector in Uniface 10.4 provides robust support for integrating MySQL databases with your enterprise applications. Key points to remember:&lt;/p&gt;

&lt;p&gt;✅ Always match the libmysql.dll architecture (32-bit/64-bit) to your Uniface installation&lt;br&gt;
✅ Use Create Table for forward engineering and Load Definitions for reverse engineering&lt;br&gt;
✅ MySQL stored procedures are fully supported&lt;br&gt;
✅ Follow Uniface naming rules and avoid MySQL reserved words&lt;br&gt;
✅ Consult the Platform Availability Matrix for version compatibility&lt;br&gt;
✅ Test thoroughly before production deployment&lt;/p&gt;

&lt;p&gt;By following these guidelines and referring to the official documentation, you can successfully integrate MySQL with your Uniface 10.4 applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sources and References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Uniface 10.4 MySQL Connector Documentation (December 15, 2025)&lt;/li&gt;
&lt;li&gt;Rocket Software Platform Availability Matrix&lt;/li&gt;
&lt;li&gt;Rocket Uniface Community Documentation&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Have you integrated MySQL with Uniface? What challenges did you encounter? Share your experiences in the comments!&lt;/strong&gt; 💬&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>uniface</category>
      <category>legacysystems</category>
      <category>databaseconnector</category>
    </item>
    <item>
      <title>🔐 Connecting Uniface 10.4 to LDAP Servers: A Complete Guide</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Tue, 23 Dec 2025 08:43:36 +0000</pubDate>
      <link>https://forem.com/f345345dfg/connecting-uniface-104-to-ldap-servers-a-complete-guide-5abc</link>
      <guid>https://forem.com/f345345dfg/connecting-uniface-104-to-ldap-servers-a-complete-guide-5abc</guid>
      <description>&lt;p&gt;&lt;strong&gt;Subtitle:&lt;/strong&gt; &lt;em&gt;Unlock the power of Directory Services in your Uniface applications with the 10.4 LDAP Connector.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the world of enterprise development, applications rarely live in isolation. They need to talk to other systems, and one of the most common requirements is authentication and user management. This is where &lt;strong&gt;LDAP&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;If you are a Uniface developer working with version 10.4, you have a powerful tool at your disposal: the &lt;strong&gt;Uniface LDAP Connector&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this guide, we will break down exactly how to configure, use, and troubleshoot this connector, with a &lt;strong&gt;special deep dive into the &lt;code&gt;addbase&lt;/code&gt; option&lt;/strong&gt;. Whether you are a veteran dealing with legacy systems or a modern developer integrating new directories, this guide is for you! 🚀&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What is LDAP? (A Quick Refresher) 📚
&lt;/h2&gt;

&lt;p&gt;Before we dive into the code, let's clarify a few terms for those who might be new to this specific domain.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;LDAP (Lightweight Directory Access Protocol):&lt;/strong&gt; Think of LDAP as a highly optimized, digital phonebook. It is a protocol used to access and manage distributed directory information services over an IP network. It's "Lightweight" because it was designed as a simpler alternative to the older, heavier &lt;strong&gt;X.500&lt;/strong&gt; standard.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;X.500:&lt;/strong&gt; This was the original "granddaddy" of directory standards. It was comprehensive but very complex and heavy on network resources. LDAP kept the directory structure of X.500 but streamlined the way we talk to it.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;IPv6:&lt;/strong&gt; You might see references to this in networking docs. It stands for "Internet Protocol version 6." It's the modern address system for the internet, replacing the older IPv4. Uniface and modern LDAP servers fully support IPv6, ensuring your application is future-proof.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In simple terms:&lt;/strong&gt; If your company uses Microsoft Active Directory (AD) or OpenLDAP to store user passwords and emails, you use LDAP to talk to it.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Uniface LDAP Connector 🔌
&lt;/h2&gt;

&lt;p&gt;Uniface doesn't treat LDAP like a weird external service; it treats it &lt;strong&gt;like a database&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is the magic of the Uniface architecture. You define an Entity (table) in your model, map it to an LDAP Object Class (like &lt;code&gt;person&lt;/code&gt; or &lt;code&gt;organizationalUnit&lt;/code&gt;), and use standard Uniface ProcScript commands (&lt;code&gt;retrieve&lt;/code&gt;, &lt;code&gt;store&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt;) to manipulate data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Capabilities:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Authentication:&lt;/strong&gt; Verify user credentials (bind).&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;CRUD Operations:&lt;/strong&gt; Create, Read, Update, and Delete directory entries.&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;SSL/TLS Support:&lt;/strong&gt; Secure your connection (essential for production).&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Hierarchy Management:&lt;/strong&gt; Navigate the tree structure of a directory.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Configuration and Setup ⚙️
&lt;/h2&gt;

&lt;p&gt;The connection behavior is controlled by the &lt;code&gt;USYS$LDP_PARAMS&lt;/code&gt; setting in your assignment file (usually &lt;code&gt;.asn&lt;/code&gt;). You configure this in the &lt;code&gt;[DRIVER_SETTINGS]&lt;/code&gt; section.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Assignment File Syntax
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[DRIVER_SETTINGS]&lt;/span&gt;
&lt;span class="err"&gt;USYS$&lt;/span&gt;&lt;span class="py"&gt;LDP_PARAMS&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;addbase=on, searchscope=sub, identifier case=lower, logon timeout=10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Options Reference
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Recommended Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;addbase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;(See Deep Dive below)&lt;/strong&gt; Controls automatic DN concatenation.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;on&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;identifier case&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Determines if field names are case-sensitive.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lower&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;logon timeout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;How long (in seconds) to wait for the server to accept a login.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;nulldefault&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Controls if empty fields are saved as &lt;code&gt;NULL&lt;/code&gt; or empty strings.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;N&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;searchscope&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines how deep the search goes (&lt;code&gt;base&lt;/code&gt;, &lt;code&gt;one&lt;/code&gt;, or &lt;code&gt;sub&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sub&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;stepsize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Controls batch fetching size. Higher values = better performance.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;50&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tls server validation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Checks if the server's certificate is valid.&lt;/td&gt;
&lt;td&gt;&lt;code&gt;on&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  4. Deep Dive: The &lt;code&gt;addbase&lt;/code&gt; Option 🕵️‍♂️
&lt;/h2&gt;

&lt;p&gt;One of the most useful (but often misunderstood) settings in the LDAP driver is &lt;code&gt;addbase&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does it do?
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;addbase&lt;/code&gt; option controls whether Uniface automatically appends the &lt;strong&gt;Base DN&lt;/strong&gt; (Distinguished Name) defined in your path to the names you use in your ProcScript code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;addbase=on&lt;/code&gt; (Default/Recommended):&lt;/strong&gt; Uniface saves you typing. You only need to provide the "Relative" Distinguished Name (RDN).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;addbase=off&lt;/code&gt;:&lt;/strong&gt; You are in full control but must provide the &lt;strong&gt;full&lt;/strong&gt; Distinguished Name for every operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example in Action
&lt;/h3&gt;

&lt;p&gt;Imagine your Base DN is &lt;code&gt;dc=example,dc=com&lt;/code&gt; and you want to search for a user named &lt;code&gt;jdoe&lt;/code&gt; inside the &lt;code&gt;users&lt;/code&gt; container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With &lt;code&gt;addbase=on&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; You write cleaner code:
read (U_NAME = "cn=jdoe,ou=users")

; Uniface actually sends this to the server:
; "cn=jdoe,ou=users,dc=example,dc=com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With &lt;code&gt;addbase=off&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; You must write the full path every time:
read (U_NAME = "cn=jdoe,ou=users,dc=example,dc=com")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When should you turn it OFF?
&lt;/h3&gt;

&lt;p&gt;You might want to set &lt;code&gt;addbase=off&lt;/code&gt; if your application needs to access objects strictly &lt;strong&gt;outside&lt;/strong&gt; of your defined Base DN, or if you are dynamically constructing complex DNs that might not follow the standard hierarchy of your main tree. For 95% of use cases, keeping it &lt;code&gt;on&lt;/code&gt; reduces bugs and makes code more readable.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Practical Use Cases &amp;amp; Code Examples 💻
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario A: User Login (Authentication)
&lt;/h3&gt;

&lt;p&gt;Instead of writing complex API calls, you simply try to "log on" to the LDAP path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; Trigger: Detail Button (Login)
variables
  string vUsername, vPassword
endvariables

vUsername = FIELD_USER
vPassword = FIELD_PASS

; Format: $logon(Path, Username, Password)
$logon("LDAP_PATH", vUsername, vPassword)

if ($status &amp;lt; 0)
  message/error "Login Failed! Check credentials."
else
  message/info "Welcome, %%vUsername! 🔓"
endif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scenario B: Searching for a User
&lt;/h3&gt;

&lt;p&gt;Assume you have modeled an entity named &lt;code&gt;INETORGPERSON&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; Trigger: Read
read
if ($status &amp;lt; 0)
   message/info "No users found."
endif
; Note: With addbase=on, the search is automatically 
; restricted to your Base DN subtree.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Platform-Specific Notes &amp;amp; Troubleshooting 🚧
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Linux vs. Windows 🐧🪟
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Windows:&lt;/strong&gt; Uses the built-in Windows Secure Channel (Schannel). It usually "just works" if your machine trusts the domain controller.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Unix/Linux:&lt;/strong&gt; You often need to explicitly point to your certificate bundle using the &lt;code&gt;tls ca file&lt;/code&gt; option.

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Example:&lt;/em&gt; &lt;code&gt;USYS$LDP_PARAMS = tls ca file=/etc/ssl/certs/ca-bundle.crt&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Common Pitfalls
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;"Table not found":&lt;/strong&gt; Your Uniface Entity name must match the LDAP Object Class exactly.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Slow Searches:&lt;/strong&gt; If &lt;code&gt;addbase=on&lt;/code&gt; and &lt;code&gt;searchscope=sub&lt;/code&gt; are set on the root of a massive directory, you might timeout. Try narrowing your Base DN in the path definition (e.g., &lt;code&gt;ou=london,dc=company,dc=com&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Connection Refused:&lt;/strong&gt; Check firewall rules and ensure IPv6 isn't blocking you if your server is configured for IPv4 only.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  7. Conclusion ✅
&lt;/h2&gt;

&lt;p&gt;The Uniface 10.4 LDAP connector bridges the gap between your sturdy legacy logic and modern directory services. By correctly utilizing options like &lt;code&gt;addbase&lt;/code&gt;, you can write cleaner, more maintainable code that integrates seamlessly with enterprise identity systems.&lt;/p&gt;

&lt;p&gt;Go ahead and integrate that directory! Happy coding! 👩‍💻👨‍💻&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Transparency Note: This article was created with AI assistance to help structure technical documentation effectively.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>ldap</category>
      <category>addbase</category>
      <category>integration</category>
    </item>
    <item>
      <title>🔐 Mastering LDAP Integration in Uniface 10.4: The Native Way</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Tue, 23 Dec 2025 08:35:35 +0000</pubDate>
      <link>https://forem.com/f345345dfg/mastering-ldap-integration-in-uniface-104-the-native-way-1ala</link>
      <guid>https://forem.com/f345345dfg/mastering-ldap-integration-in-uniface-104-the-native-way-1ala</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was created with AI assistance, synthesizing official Rocket Uniface 10.4 documentation with practical implementation patterns.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Connecting legacy enterprise applications to modern directory services is a classic integration challenge. While many developers attempt to build complex wrappers or external call-outs, Uniface 10.4 provides a native &lt;strong&gt;LDAP Connector (LDP)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This connector is powerful because it allows you to treat a hierarchical Directory Service almost exactly like a relational database. This guide will show you how to configure and use it correctly using native ProcScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 What is LDAP? (For the Uninitiated)
&lt;/h2&gt;

&lt;p&gt;Before we dive into code, let's clarify the terminology:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;LDAP (Lightweight Directory Access Protocol)&lt;/strong&gt;: Think of it as a specialized database optimized for &lt;strong&gt;reading&lt;/strong&gt; data. Unlike a standard SQL database that balances reading and writing, LDAP is designed for scenarios where you write once (create a user) but read millions of times (verify a login).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;X.500&lt;/strong&gt;: This is the "grandparent" standard. It defined the comprehensive model for directory services. LDAP was created as a lighter, more efficient way (via TCP/IP) to access X.500 directories. Uniface supports both pure LDAP and X.500 gateways.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;IPv6&lt;/strong&gt;: The modern version of the Internet Protocol. The Uniface LDAP connector is fully compatible with IPv6 addresses (e.g., &lt;code&gt;[2001:db8::1]&lt;/code&gt;), ensuring your application is future-proof.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔌 The Uniface Approach: Driver, Not Service
&lt;/h2&gt;

&lt;p&gt;A common misconception is that you "call" LDAP like a web service. In Uniface, you don't. You use the &lt;strong&gt;LDP driver&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This means you interact with LDAP using standard Uniface I/O commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;retrieve&lt;/code&gt; to search for users.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;open&lt;/code&gt; to authenticate.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;store&lt;/code&gt; to update attributes (if permissions allow).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠️ Step 1: Configuration (The ASN File)
&lt;/h2&gt;

&lt;p&gt;The magic happens in the Assignment File (&lt;code&gt;.asn&lt;/code&gt;). You need to define the driver and map a logical path to your LDAP server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[SETTINGS]&lt;/span&gt;
&lt;span class="c"&gt;; Load the LDAP driver (ensure the version matches your install, e.g., U3.0 or similar)
&lt;/span&gt;&lt;span class="err"&gt;USYS$&lt;/span&gt;&lt;span class="py"&gt;LDP&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;LDP&lt;/span&gt;

&lt;span class="c"&gt;; Enable debug logging - crucial for seeing what happens under the hood!
&lt;/span&gt;&lt;span class="py"&gt;LDAP_DEBUG&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1&lt;/span&gt;
&lt;span class="py"&gt;LDAP_TIMEOUT&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;10&lt;/span&gt;

&lt;span class="nn"&gt;[PATHS]&lt;/span&gt;
&lt;span class="c"&gt;; Syntax: $PATH_NAME = LDP:ServerName:Port:BaseDN
; 'BaseDN' is the root folder where your search begins.
&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;AD_PROD&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;LDP:ad.company.com:389:DC=company,DC=com&lt;/span&gt;

&lt;span class="c"&gt;; For SSL/TLS (LDAPS), typically use port 636
&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;AD_SECURE&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;LDP:ad.company.com:636:DC=company,DC=com&lt;/span&gt;

&lt;span class="nn"&gt;[ENTITIES]&lt;/span&gt;
&lt;span class="c"&gt;; Map your Uniface entities to the logical path
&lt;/span&gt;&lt;span class="py"&gt;USER.AD&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$AD_PROD&lt;/span&gt;
&lt;span class="py"&gt;GROUP.AD&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;$AD_PROD&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📝 Step 2: The Data Model
&lt;/h2&gt;

&lt;p&gt;LDAP is hierarchical, but Uniface is relational. We bridge this gap by mapping:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;LDAP Class&lt;/strong&gt; ➡️ &lt;strong&gt;Uniface Entity&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Distinguished Name (DN)&lt;/strong&gt; ➡️ &lt;strong&gt;Primary Key&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In your Uniface Model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Create an entity (e.g., &lt;code&gt;USER&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;  Create a field &lt;code&gt;DN&lt;/code&gt; (String, approx C256) and mark it as the &lt;strong&gt;Primary Key&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Create fields for attributes you want (e.g., &lt;code&gt;CN&lt;/code&gt;, &lt;code&gt;MAIL&lt;/code&gt;, &lt;code&gt;TELEPHONENUMBER&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Important:&lt;/strong&gt; The field names in Uniface must match the LDAP attribute names (case-insensitive in Uniface, but usually lowercase in LDAP schema).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  💻 Step 3: Practical Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Case A: User Authentication (The Login)
&lt;/h3&gt;

&lt;p&gt;To check a password, we don't need a complex query. We simply try to &lt;strong&gt;open a connection&lt;/strong&gt; using the specific user's credentials. If the server accepts the connection, the password is correct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operation user_login
params
    string p_username : IN
    string p_password : IN
endparams

variables
    string v_connection_string
endvariables

    ; Construct the dynamic path string
    ; Syntax: LDP:Host:Port:BaseDN|Username|Password
    ; Note: Active Directory often requires 'domain\user' or 'user@domain'
    v_connection_string = "LDP:ad.company.com:389:DC=company,DC=com|%%p_username|%%p_password"

    ; Attempt to open the path
    ; The 'b' flag is best practice here to skip table verification checks
    open v_connection_string, "b"

    if ($status &amp;lt; 0)
        ; Connection refused (Wrong password, account locked, or server down)
        return -1
    endif

    ; Security Best Practice: Close the connection immediately!
    ; You don't want to keep a session open with the user's privileges.
    close v_connection_string

    return 1 ; Success
endoperation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use Case B: Finding a User (The Search)
&lt;/h3&gt;

&lt;p&gt;To find a user, use the standard &lt;code&gt;retrieve&lt;/code&gt; command. Uniface translates your profile fields into an LDAP filter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;operation find_employee
params
    string p_search_name : IN
endparams

    clear/e "USER"

    ; Set the search profile
    ; This translates to an LDAP filter like (cn=Smith*)
    CN.USER = "%%p_search_name%%*"

    ; Execute the search
    retrieve/e "USER"

    if ($status &amp;lt; 0)
        message "Error or no data found: %%$status"
        return
    endif

    ; Loop through results
    setocc "USER", 1
    while ($status &amp;gt; 0)
        putmess "Found: %%CN.USER - %%MAIL.USER"
        setocc "USER", $orc + 1
    endwhile
endoperation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🐧 Platform Specifics: Linux vs. Windows
&lt;/h2&gt;

&lt;p&gt;While the ProcScript code stays the same, the environment setup differs slightly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Windows 🪟
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Certificates:&lt;/strong&gt; The connector typically uses the Windows Certificate Store. If your organization uses a private CA for LDAPS, ensure the Root CA is installed in the Windows Trusted Root store.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Authentication:&lt;/strong&gt; Integration with Active Directory is usually seamless.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Linux 🐧
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Certificates:&lt;/strong&gt; You must explicitly tell the driver where to find certificates if they aren't in the standard OpenSSL location. Add this to your &lt;code&gt;.asn&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[SETTINGS]&lt;/span&gt;
&lt;span class="py"&gt;LDAP_CACERTFILE&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/etc/pki/tls/certs/ca-bundle.crt&lt;/span&gt;
&lt;span class="py"&gt;LDAP_CERTFILE&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/path/to/client-cert.pem&lt;/span&gt;
&lt;span class="py"&gt;LDAP_KEYFILE&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/path/to/client-key.pem&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚡ Troubleshooting &amp;amp; Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;"Table Not Found" (-13):&lt;/strong&gt; This is the most common error. It usually means your &lt;strong&gt;Base DN&lt;/strong&gt; is incorrect. If Uniface looks in &lt;code&gt;OU=Sales&lt;/code&gt; but the user is in &lt;code&gt;OU=IT&lt;/code&gt;, it won't find the "table" (object).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Performance:&lt;/strong&gt; Never do a &lt;code&gt;retrieve&lt;/code&gt; without setting a profile field (like &lt;code&gt;CN&lt;/code&gt; or &lt;code&gt;SAMACCOUNTNAME&lt;/code&gt;). An unbounded search attempts to download the &lt;em&gt;entire&lt;/em&gt; directory, which will time out or crash your application.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Encoding:&lt;/strong&gt; LDAP v3 uses &lt;strong&gt;UTF-8&lt;/strong&gt;. Ensure your Uniface application handles Unicode correctly, otherwise, characters like &lt;code&gt;é&lt;/code&gt; or &lt;code&gt;ü&lt;/code&gt; in names will appear corrupted.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Read-Only Mindset:&lt;/strong&gt; While &lt;code&gt;store&lt;/code&gt; commands exist, AD permissions are complex. It is generally safer and easier to use Uniface for &lt;strong&gt;reading/authenticating&lt;/strong&gt; and use specialized tools (or PowerShell scripts invoked by Uniface) for creating accounts.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🏁 Conclusion
&lt;/h2&gt;

&lt;p&gt;The Uniface LDAP connector eliminates the need for external DLLs or Java wrappers. By understanding that LDAP is just another "database" to Uniface, you can use the standard commands you already know (&lt;code&gt;open&lt;/code&gt;, &lt;code&gt;retrieve&lt;/code&gt;) to build secure, integrated enterprise applications.&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>ldap</category>
      <category>integration</category>
      <category>legacy</category>
    </item>
    <item>
      <title>Connecting Uniface 10.4 to LDAP Servers: A Complete Guide 🔐</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Tue, 23 Dec 2025 08:27:13 +0000</pubDate>
      <link>https://forem.com/f345345dfg/connecting-uniface-104-to-ldap-servers-a-complete-guide-2f3f</link>
      <guid>https://forem.com/f345345dfg/connecting-uniface-104-to-ldap-servers-a-complete-guide-2f3f</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was created with AI assistance to provide accurate technical documentation for the developer community.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you're working with legacy enterprise systems, you've probably encountered the challenge of integrating directory services. Today, I'll walk you through the &lt;strong&gt;Uniface 10.4 LDAP Connector&lt;/strong&gt; - a powerful tool that bridges the gap between your Uniface applications and enterprise directory services.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is LDAP?&lt;/li&gt;
&lt;li&gt;Understanding the Uniface LDAP Connector&lt;/li&gt;
&lt;li&gt;Supported Features and Operations&lt;/li&gt;
&lt;li&gt;Real-World Use Cases&lt;/li&gt;
&lt;li&gt;Configuration and Setup&lt;/li&gt;
&lt;li&gt;Platform-Specific Considerations&lt;/li&gt;
&lt;li&gt;Best Practices and Common Issues&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is LDAP? 🤔
&lt;/h2&gt;

&lt;p&gt;Before diving into the Uniface connector, let's understand what LDAP actually is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LDAP (Lightweight Directory Access Protocol)&lt;/strong&gt; is an industry-standard protocol used to access and manage directory information services over a network. Think of it as a specialized database optimized for read-heavy operations, storing information in a hierarchical tree structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Concepts:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;📖 X.500 Standard&lt;/strong&gt;: LDAP was originally designed as a lightweight alternative to the X.500 Directory Access Protocol (DAP). While X.500 required the heavy OSI protocol stack, LDAP runs directly over TCP/IP, making it much more practical for modern networks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🌳 Hierarchical Structure&lt;/strong&gt;: Data in LDAP is organized like a tree, with a root at the top and branches leading to individual entries (called "Distinguished Names" or DNs).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔍 Common Operations&lt;/strong&gt;: LDAP supports standard operations including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Search&lt;/strong&gt;: Query the directory for specific entries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bind&lt;/strong&gt;: Authenticate a user (verify credentials)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add&lt;/strong&gt;: Create new directory entries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modify&lt;/strong&gt;: Update existing entries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete&lt;/strong&gt;: Remove entries from the directory&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Use LDAP?
&lt;/h3&gt;

&lt;p&gt;LDAP is perfect for centralized authentication in enterprise environments. Instead of managing user credentials separately in each application, you maintain a single source of truth. Applications like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jenkins 🛠️&lt;/li&gt;
&lt;li&gt;Kubernetes ☸️&lt;/li&gt;
&lt;li&gt;OpenVPN 🔒&lt;/li&gt;
&lt;li&gt;Atlassian products (Jira, Confluence) 📊&lt;/li&gt;
&lt;li&gt;Samba file servers 📁&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...all commonly integrate with LDAP directories for user authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Uniface LDAP Connector 🔌
&lt;/h2&gt;

&lt;p&gt;The Uniface LDAP connector (mnemonic: &lt;strong&gt;LDP&lt;/strong&gt;) enables Uniface applications to communicate with LDAP servers seamlessly. This includes both standalone LDAP servers and X.500 Directory System Agents with an LDAP gateway.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Specifications:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Specification&lt;/th&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Connector Mnemonic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LDP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Protocol Version&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LDAP V3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows Implementation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Native LDAP (32-bit and 64-bit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Unix/Linux Implementation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;OpenLDAP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Connection Types&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;TCP (unencrypted) and TLS (encrypted)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Unicode Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full Unicode range (independent of $DEF_CHARSET)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Important IPv6 Note 🌐
&lt;/h3&gt;

&lt;p&gt;The LDP connector supports &lt;strong&gt;IPv6 through hostname resolution&lt;/strong&gt; using DNS or the local hosts file. However, direct IPv6 address input is not yet available. This means you'll need to configure DNS entries or host file entries for IPv6-enabled LDAP servers rather than using literal IPv6 addresses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Instead of using literal IPv6 address
ldap://[2001:db8::1]:389  ❌

# Use hostname resolution
ldap://ldap-server.example.com:389  ✅
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Supported Features and Operations 🛠️
&lt;/h2&gt;

&lt;p&gt;The Uniface LDAP connector provides comprehensive functionality within the limitations of the LDAP protocol:&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Capabilities:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;✅ Read Operations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieve individual entries by Distinguished Name (DN)&lt;/li&gt;
&lt;li&gt;Access specific attributes from directory entries&lt;/li&gt;
&lt;li&gt;Handle multi-valued attributes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Write Operations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create new entries in the LDAP directory&lt;/li&gt;
&lt;li&gt;Update existing entries (modify attributes)&lt;/li&gt;
&lt;li&gt;Delete entries from the directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Search Operations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute complex search queries with filters&lt;/li&gt;
&lt;li&gt;Search across subtrees or single levels&lt;/li&gt;
&lt;li&gt;Return specific attributes or complete entries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Connection Management&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Establish secure connections using TLS&lt;/li&gt;
&lt;li&gt;Authenticate using credentials stored in .asn files&lt;/li&gt;
&lt;li&gt;Close connections gracefully&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Through .asn Files 📝
&lt;/h3&gt;

&lt;p&gt;All connection settings are stored in Uniface assignment files (.asn). This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Server address and port&lt;/strong&gt;: Where to connect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Base DN&lt;/strong&gt;: The starting point in the directory tree&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication credentials&lt;/strong&gt;: Username and password for binding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connection parameters&lt;/strong&gt;: Timeout values, SSL/TLS settings&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Use Cases 💼
&lt;/h2&gt;

&lt;p&gt;Let's explore practical scenarios where the Uniface LDAP connector shines:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Enterprise Single Sign-On (SSO)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: A large organization uses Uniface applications for business operations and needs centralized authentication.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; Example: Authenticate user against LDAP
operation AuthenticateUser
  parameters
    string vUsername
    string vPassword
  endparameters

  variables
    string vDN
    string vResult
  endvariables

  ; Build Distinguished Name
  vDN = "uid=%%vUsername%%,ou=users,dc=company,dc=org"

  ; Attempt LDAP bind
  activate "LDAP_AUTH".bind(vDN, vPassword)

  ; Check result
  if ($status = 0)
    putmess "Authentication successful"
  else
    putmess "Authentication failed"
  endif

end ; AuthenticateUser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. User Profile Synchronization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: Automatically sync user information from Active Directory to Uniface application entities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; Example: Retrieve user details from LDAP
operation GetUserProfile
  parameters
    string vUsername
  endparameters

  variables
    string vEmail
    string vFullName
    string vDepartment
  endvariables

  ; Search for user
  retrieve LDAP_USER, 1
    where (LDAP_USER.UID = vUsername)

  if ($status = 0)
    ; Map LDAP attributes to variables
    vEmail = LDAP_USER.MAIL
    vFullName = LDAP_USER.CN
    vDepartment = LDAP_USER.DEPARTMENT
  endif

end ; GetUserProfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Dynamic Group Management
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;: Query LDAP groups to determine user permissions dynamically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-world benefit&lt;/strong&gt;: Instead of maintaining duplicate group memberships in your Uniface database, query LDAP at runtime to check if users belong to specific groups (e.g., "Administrators", "Finance_Staff", "ReadOnly_Users").&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration and Setup ⚙️
&lt;/h2&gt;

&lt;p&gt;Here's how to configure the Uniface LDAP connector step by step:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Configure the .asn File
&lt;/h3&gt;

&lt;p&gt;Create or edit your assignment file with LDAP settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[DRIVER_SETTINGS]&lt;/span&gt;
&lt;span class="c"&gt;; Define the LDAP connector
&lt;/span&gt;&lt;span class="py"&gt;LDAP_DRIVER&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;LDP&lt;/span&gt;

&lt;span class="nn"&gt;[ENTITIES]&lt;/span&gt;
&lt;span class="c"&gt;; Map your Uniface entities to LDAP structure
&lt;/span&gt;&lt;span class="py"&gt;LDAP_USER&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;LDAP_DRIVER, ou=users,dc=company,dc=com&lt;/span&gt;
&lt;span class="py"&gt;LDAP_GROUP&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;LDAP_DRIVER, ou=groups,dc=company,dc=com&lt;/span&gt;

&lt;span class="nn"&gt;[LDAP_DRIVER]&lt;/span&gt;
&lt;span class="c"&gt;; Connection parameters
&lt;/span&gt;&lt;span class="py"&gt;Server&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ldap.company.com&lt;/span&gt;
&lt;span class="py"&gt;Port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;389&lt;/span&gt;
&lt;span class="c"&gt;; For TLS/SSL connection use port 636
&lt;/span&gt;
&lt;span class="c"&gt;; Base DN for searches
&lt;/span&gt;&lt;span class="py"&gt;BaseDN&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;dc=company,dc=com&lt;/span&gt;

&lt;span class="c"&gt;; Bind credentials (authentication)
&lt;/span&gt;&lt;span class="py"&gt;BindDN&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;cn=uniface_service,ou=service_accounts,dc=company,dc=com&lt;/span&gt;
&lt;span class="py"&gt;BindPassword&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;YourSecurePassword&lt;/span&gt;

&lt;span class="c"&gt;; Connection options
&lt;/span&gt;&lt;span class="py"&gt;Timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;30&lt;/span&gt;
&lt;span class="py"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Define Entity Keys
&lt;/h3&gt;

&lt;p&gt;Each LDAP entity in your Uniface model needs a unique identifier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[LDAP_USER]&lt;/span&gt;
&lt;span class="c"&gt;; Define the key attribute
&lt;/span&gt;&lt;span class="py"&gt;Key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;uid&lt;/span&gt;

&lt;span class="c"&gt;; Map Uniface fields to LDAP attributes
&lt;/span&gt;&lt;span class="py"&gt;UID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;uid&lt;/span&gt;
&lt;span class="py"&gt;EMAIL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;mail&lt;/span&gt;
&lt;span class="py"&gt;FULL_NAME&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;cn&lt;/span&gt;
&lt;span class="py"&gt;FIRST_NAME&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;givenName&lt;/span&gt;
&lt;span class="py"&gt;LAST_NAME&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;sn&lt;/span&gt;
&lt;span class="py"&gt;DEPARTMENT&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ou&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Enable TLS/SSL (Recommended) 🔒
&lt;/h3&gt;

&lt;p&gt;For production environments, always use encrypted connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[LDAP_DRIVER]&lt;/span&gt;
&lt;span class="py"&gt;Server&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ldaps.company.com&lt;/span&gt;
&lt;span class="py"&gt;Port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;636&lt;/span&gt;
&lt;span class="py"&gt;SSL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
&lt;span class="c"&gt;; or for STARTTLS on port 389
&lt;/span&gt;&lt;span class="py"&gt;UseTLS&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security Best Practice&lt;/strong&gt;: Never store credentials in plain text in production .asn files. Use environment variables or encrypted configuration management tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Test the Connection
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; Test LDAP connectivity
operation TestLDAPConnection
  variables
    string vResult
  endvariables

  ; Attempt to open connection
  activate "LDAP_DRIVER".open

  if ($status = 0)
    putmess "LDAP connection successful!"
    activate "LDAP_DRIVER".close
  else
    putmess "Connection failed: %%$status%%"
  endif

end ; TestLDAPConnection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Platform-Specific Considerations 🖥️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Linux/Unix Requirements
&lt;/h3&gt;

&lt;p&gt;On Linux systems, the LDAP connector requires the OpenLDAP package to be installed:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debian/Ubuntu:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;slapd ldap-utils libldap-2.4-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Red Hat/CentOS:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;openldap openldap-clients openldap-servers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SUSE/openSUSE:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;zypper &lt;span class="nb"&gt;install &lt;/span&gt;openldap2 openldap2-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;⚠️ Important&lt;/strong&gt;: Make sure you install the OpenLDAP version that is current for your operating system version. Outdated packages may have security vulnerabilities or compatibility issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Windows Considerations
&lt;/h3&gt;

&lt;p&gt;Windows systems use the native LDAP implementation (Wldap32.dll), which is included with the operating system. No additional packages are required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Active Directory Integration&lt;/strong&gt;: When connecting to Microsoft Active Directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[AD_DRIVER]&lt;/span&gt;
&lt;span class="py"&gt;Server&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ad.company.local&lt;/span&gt;
&lt;span class="py"&gt;Port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;389&lt;/span&gt;
&lt;span class="c"&gt;; Use Windows domain format for bind DN
&lt;/span&gt;&lt;span class="py"&gt;BindDN&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;COMPANY&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;uniface_service&lt;/span&gt;
&lt;span class="c"&gt;; or UPN format
&lt;/span&gt;&lt;span class="py"&gt;BindDN&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;uniface_service@company.local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Platform Independence ✨
&lt;/h3&gt;

&lt;p&gt;One of LDAP's greatest strengths is its platform independence. Unlike Active Directory (which is Windows-centric), LDAP works seamlessly across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows Server environments&lt;/li&gt;
&lt;li&gt;Linux/Unix systems&lt;/li&gt;
&lt;li&gt;macOS&lt;/li&gt;
&lt;li&gt;Mixed heterogeneous networks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the Uniface LDAP connector ideal for organizations with diverse infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices and Common Issues 🎯
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Security Best Practices 🔐
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Always Use TLS/SSL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Never send credentials over unencrypted connections in production:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;; ❌ Insecure
&lt;/span&gt;&lt;span class="py"&gt;Port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;389&lt;/span&gt;
&lt;span class="py"&gt;SSL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;no&lt;/span&gt;

&lt;span class="c"&gt;; ✅ Secure
&lt;/span&gt;&lt;span class="py"&gt;Port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;636&lt;/span&gt;
&lt;span class="py"&gt;SSL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Use Service Accounts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create dedicated LDAP service accounts for Uniface applications with minimal required privileges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Example: Create restricted service account
dn: cn=uniface_service,ou=service_accounts,dc=company,dc=com
objectClass: inetOrgPerson
cn: uniface_service
sn: Service Account
userPassword: {SSHA}encrypted_hash_here
description: Uniface application authentication service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Implement Connection Pooling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reuse LDAP connections where possible to reduce overhead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; Keep connection open for multiple operations
activate "LDAP_DRIVER".open

; Perform multiple operations...
; ... retrieve user 1
; ... retrieve user 2
; ... search groups

; Close when done
activate "LDAP_DRIVER".close
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common Issues and Solutions 🔧
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Issue 1: Authentication Failures
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Bind operations fail with "Invalid credentials" error&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common Causes&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Incorrect BindDN format&lt;/li&gt;
&lt;li&gt;Expired service account password&lt;/li&gt;
&lt;li&gt;Insufficient permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test credentials manually&lt;/span&gt;
ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://server:389 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s2"&gt;"cn=uniface_service,ou=service_accounts,dc=company,dc=com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-W&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"dc=company,dc=com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"(objectClass=*)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Issue 2: Connection Timeouts
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Operations hang or timeout&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common Causes&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firewall blocking LDAP ports (389, 636)&lt;/li&gt;
&lt;li&gt;Network latency&lt;/li&gt;
&lt;li&gt;LDAP server overloaded&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;; Increase timeout values
&lt;/span&gt;&lt;span class="nn"&gt;[LDAP_DRIVER]&lt;/span&gt;
&lt;span class="py"&gt;Timeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;60&lt;/span&gt;
&lt;span class="py"&gt;NetworkTimeout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Issue 3: SSL/TLS Certificate Errors
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: "Certificate verification failed" errors&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common Causes&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self-signed certificates not trusted&lt;/li&gt;
&lt;li&gt;Expired certificates&lt;/li&gt;
&lt;li&gt;Hostname mismatch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add CA certificate to trusted store (Linux)&lt;/span&gt;
&lt;span class="nb"&gt;sudo cp &lt;/span&gt;ldap-ca-cert.pem /usr/local/share/ca-certificates/
&lt;span class="nb"&gt;sudo &lt;/span&gt;update-ca-certificates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Issue 4: Character Encoding Problems
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Special characters (ä, ö, ü, ß, é, ñ) displayed incorrectly&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: The Uniface LDAP connector uses Unicode exclusively. Ensure your .asn file specifies UTF-8 encoding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[SETTINGS]&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;NLS_ENCODING&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;UTF-8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Issue 5: Performance Issues with Large Directories
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Slow search operations&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Use indexed attributes and implement pagination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; Use paged results for large searches
operation SearchUsersWithPaging
  variables
    numeric vPageSize
    string vCookie
  endvariables

  vPageSize = 100

  ; Implement paging logic
  ; (pseudocode - actual implementation varies)

end ; SearchUsersWithPaging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testing and Debugging Tips 🔍
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Use LDAP Browser Tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tools like Apache Directory Studio or JXplorer help you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visualize directory structure&lt;/li&gt;
&lt;li&gt;Test search filters&lt;/li&gt;
&lt;li&gt;Verify attribute names&lt;/li&gt;
&lt;li&gt;Check permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Enable Verbose Logging&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[SETTINGS]&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;LDAP_DEBUG&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="py"&gt;TRACE&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ALL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Test with Command-Line Tools&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test basic connectivity&lt;/span&gt;
ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://server:389 &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"dc=company,dc=com"&lt;/span&gt;

&lt;span class="c"&gt;# Test TLS&lt;/span&gt;
ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://server:389 &lt;span class="nt"&gt;-ZZ&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"dc=company,dc=com"&lt;/span&gt;

&lt;span class="c"&gt;# Test authentication&lt;/span&gt;
ldapsearch &lt;span class="nt"&gt;-x&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; ldap://server:389 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s2"&gt;"cn=user,dc=company,dc=com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-W&lt;/span&gt; &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="s2"&gt;"dc=company,dc=com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion 🎉
&lt;/h2&gt;

&lt;p&gt;The Uniface 10.4 LDAP Connector is a powerful integration tool that brings enterprise-grade directory services to your legacy applications. By understanding its capabilities and following best practices, you can:&lt;/p&gt;

&lt;p&gt;✅ Implement centralized authentication&lt;br&gt;&lt;br&gt;
✅ Reduce administrative overhead&lt;br&gt;&lt;br&gt;
✅ Improve security posture&lt;br&gt;&lt;br&gt;
✅ Enable SSO capabilities&lt;br&gt;&lt;br&gt;
✅ Integrate seamlessly with existing infrastructure  &lt;/p&gt;

&lt;h3&gt;
  
  
  Key Takeaways:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;LDAP is a protocol&lt;/strong&gt;, not a product - it works across platforms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;X.500 compatibility&lt;/strong&gt; means broad directory support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TLS/SSL is mandatory&lt;/strong&gt; for production environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IPv6 support&lt;/strong&gt; requires DNS hostname resolution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform-specific requirements&lt;/strong&gt; vary (OpenLDAP on Linux, native on Windows)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Next Steps 🚀
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Review your organization's LDAP directory structure&lt;/li&gt;
&lt;li&gt;Install required OpenLDAP packages (Linux)&lt;/li&gt;
&lt;li&gt;Configure your .asn file with connection parameters&lt;/li&gt;
&lt;li&gt;Test authentication in a development environment&lt;/li&gt;
&lt;li&gt;Implement proper error handling&lt;/li&gt;
&lt;li&gt;Plan migration strategy for production&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Resources 📚
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.rocketsoftware.com/bundle/uniface_104/" rel="noopener noreferrer"&gt;Uniface 10.4 Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.openldap.org/doc/" rel="noopener noreferrer"&gt;OpenLDAP Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://datatracker.ietf.org/doc/html/rfc4511" rel="noopener noreferrer"&gt;LDAP RFC 4511&lt;/a&gt; - Protocol Specification&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.itu.int/rec/T-REC-X.500/" rel="noopener noreferrer"&gt;X.500 Standard Overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Have you integrated Uniface with LDAP?&lt;/strong&gt; Share your experiences, challenges, or tips in the comments below! 💬&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note: This guide is based on Uniface 10.4 documentation. Always refer to your specific version's documentation and consult with your system administrators before implementing changes in production environments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>ldap</category>
      <category>enterprisedevelopment</category>
      <category>legacysystems</category>
    </item>
    <item>
      <title>Uniface 10.4 &amp; Informix: Decoding Error Messages 🔍</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Tue, 23 Dec 2025 08:08:39 +0000</pubDate>
      <link>https://forem.com/f345345dfg/uniface-104-informix-decoding-error-messages-24e2</link>
      <guid>https://forem.com/f345345dfg/uniface-104-informix-decoding-error-messages-24e2</guid>
      <description>&lt;p&gt;Hey developers! 👋&lt;/p&gt;

&lt;p&gt;If you work with &lt;strong&gt;Uniface 10.4&lt;/strong&gt; and &lt;strong&gt;Informix&lt;/strong&gt;, you know that robust error handling is key. Sometimes, the message frame shows you an error, but it can be confusing. Is it Uniface? Is it the Connector? Is it the Informix database itself?&lt;/p&gt;

&lt;p&gt;In this post, I will help you understand the different types of error messages and give you a &lt;strong&gt;cheat sheet&lt;/strong&gt; for the specific Connector return values.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;🤖 This blog post was created with the help of an AI assistant, based on the official Uniface documentation.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Two Types of Messages 📧
&lt;/h2&gt;

&lt;p&gt;First, you need to spot the difference between a &lt;strong&gt;Connector&lt;/strong&gt; error and a native &lt;strong&gt;Informix&lt;/strong&gt; error. They look different in the message frame.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Connector Errors
&lt;/h3&gt;

&lt;p&gt;These are errors generated by the Uniface driver itself (before or during communication with the database).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connector {ERROR|WARNING} (Number): Message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Informix Errors
&lt;/h3&gt;

&lt;p&gt;These come directly from the DBMS. They include the SQLSTATE and SQLCODE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Informix {ERROR|WARNING|NO DATA} (SQLSTATE: sqlstate ): Message SQLCODE sqlcode: Message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The $dberror Variable 🕵️
&lt;/h2&gt;

&lt;p&gt;When an error happens, Uniface stores the last error code in the &lt;code&gt;$dberror&lt;/code&gt; variable. This is what you check in your ProcScript code.&lt;/p&gt;

&lt;p&gt;Here is the breakdown of what the values in &lt;code&gt;$dberror&lt;/code&gt; mean:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Success, no error. Everything worked perfectly. ✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&amp;lt; 0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Error detected by Informix. A negative number means the DBMS reported an issue. 🔴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;20–29&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Connector errors. A positive number in this range means the Connector found an issue. 🟠&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Connector Error Cheat Sheet 📝
&lt;/h2&gt;

&lt;p&gt;If you see a positive number in &lt;code&gt;$dberror&lt;/code&gt; between 20 and 29, it is one of these specific Connector issues. Keep this list handy!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;$dberror&lt;/th&gt;
&lt;th&gt;Message&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The requested function/mode is not supported.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;21&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The specified database environment name is too long.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;22&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The connector can fetch by primary key only.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;23&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No more cursors could be allocated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;24&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No more statements could be allocated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Connector deleted/updated more or less than 1 row.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;26&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The parsed SQL statement was not a select.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;27&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;An illegal request was received by the connector.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;28&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Already logged on to a database.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;29&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unrecognized option for open database.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Examples in Action 🚀
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Example 1: Success (Error 0)
&lt;/h3&gt;

&lt;p&gt;You fetch a record successfully from the Informix database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Result in &lt;code&gt;$dberror&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Message&lt;/strong&gt;: No error message appears.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example 2: Already Logged On (Error 28)
&lt;/h3&gt;

&lt;p&gt;Your code tries to open a connection to the database, but your path is already open.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Result in &lt;code&gt;$dberror&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;28&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Message&lt;/strong&gt;: &lt;code&gt;Connector ERROR (28): Already logged on to a database.&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example 3: Informix Error (Negative Value)
&lt;/h3&gt;

&lt;p&gt;The Informix DBMS reports an error (for example, a syntax error in your SQL or a constraint violation).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Result in &lt;code&gt;$dberror&lt;/code&gt;&lt;/strong&gt;: A negative number (example: &lt;code&gt;-201&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Message&lt;/strong&gt;: &lt;code&gt;Informix ERROR (SQLSTATE: 42000): ... SQLCODE -201: ...&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick Tips 💡
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  ✨ Always check &lt;code&gt;$dberror&lt;/code&gt; after database operations.&lt;/li&gt;
&lt;li&gt;  ✨ If &lt;code&gt;$dberror&lt;/code&gt; is positive and between 20–29, use the table above to find the cause.&lt;/li&gt;
&lt;li&gt;  ✨ If &lt;code&gt;$dberror&lt;/code&gt; is negative, contact Informix documentation for the SQLCODE meaning.&lt;/li&gt;
&lt;li&gt;  ✨ Look at both the error &lt;strong&gt;number&lt;/strong&gt; and the &lt;strong&gt;message&lt;/strong&gt; to debug faster.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Next time you see an error in the message frame, check the syntax first. Is it "Connector" or "Informix"? If it is a Connector error, use the table above to quickly find the cause!&lt;/p&gt;

&lt;p&gt;Happy coding! 💻✨&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>informix</category>
      <category>dberror</category>
      <category>database</category>
    </item>
    <item>
      <title>Uniface 10.4 + Informix: Simple Guide to Data Packing 📦</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Tue, 23 Dec 2025 08:02:54 +0000</pubDate>
      <link>https://forem.com/f345345dfg/uniface-104-informix-simple-guide-to-data-packing-4n9d</link>
      <guid>https://forem.com/f345345dfg/uniface-104-informix-simple-guide-to-data-packing-4n9d</guid>
      <description>&lt;p&gt;&lt;em&gt;🤖 This blog post was created with the help of an AI assistant and is based on the Uniface 10.4 documentation about “Informix Data Packing”.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you use Uniface 10.4 with an Informix database, every field in your model has a packing code. This packing code tells Informix how the data is stored in the database. 😊&lt;/p&gt;

&lt;p&gt;In this article, you see how Uniface packing codes map to Informix storage formats, in simple language and with small examples. This can help you avoid strange data problems when you design or debug your application. 💡&lt;/p&gt;




&lt;h2&gt;
  
  
  What is data packing?
&lt;/h2&gt;

&lt;p&gt;In Uniface, each field has a data type and a packing code, for example &lt;code&gt;C10&lt;/code&gt; or &lt;code&gt;I4&lt;/code&gt;. The packing code controls how the data is stored physically in the Informix table (for example as &lt;code&gt;CHAR&lt;/code&gt;, &lt;code&gt;VARCHAR&lt;/code&gt;, &lt;code&gt;DECIMAL&lt;/code&gt; or &lt;code&gt;DATE&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The Informix connector uses a fixed mapping from the Uniface packing code to the Informix storage format. This means that the same packing code always results in the same Informix data type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Very small example
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;C10&lt;/code&gt; in Uniface → stored as &lt;code&gt;CHAR(10)&lt;/code&gt; in Informix.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;I4&lt;/code&gt; in Uniface → stored as &lt;code&gt;INTEGER&lt;/code&gt; in Informix.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;D&lt;/code&gt; in Uniface → stored as &lt;code&gt;DATE&lt;/code&gt; in Informix.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the table is created in Informix, this mapping is fixed for that column unless you change the table definition with SQL. So choosing the right packing code is important already in the Uniface model.&lt;/p&gt;




&lt;h2&gt;
  
  
  Character and text fields 📝
&lt;/h2&gt;

&lt;p&gt;Many Uniface packing codes become simple character types in Informix. These are used for names, codes, flags and other text data that is not extremely large.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;B&lt;/strong&gt;, &lt;strong&gt;B1-B5&lt;/strong&gt; → stored as &lt;code&gt;CHAR&lt;/code&gt; in Informix (for example for boolean-like fields stored as &lt;code&gt;Y&lt;/code&gt;/&lt;code&gt;N&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt;/&lt;code&gt;1&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;C1-C*&lt;/strong&gt; → stored as &lt;code&gt;CHAR&lt;/code&gt; (fixed-length character fields).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;R1-R*&lt;/strong&gt; → stored as &lt;code&gt;CHAR&lt;/code&gt; (often used for raw codes).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;(S)A1-A9&lt;/strong&gt; → stored as &lt;code&gt;CHAR&lt;/code&gt; (short strings).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;(S)A11-A40&lt;/strong&gt; → stored as &lt;code&gt;CHAR&lt;/code&gt; (longer strings).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;T&lt;/strong&gt;, &lt;strong&gt;T1-T2&lt;/strong&gt; → stored as &lt;code&gt;CHAR&lt;/code&gt; (small text or time-related codes).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;U1-U*&lt;/strong&gt; → stored as &lt;code&gt;CHAR&lt;/code&gt; (Unicode string handled as character data by the connector).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;VC1-VC255&lt;/strong&gt;, &lt;strong&gt;VR1-VR255&lt;/strong&gt;, &lt;strong&gt;VU1-VU255&lt;/strong&gt; → stored as &lt;code&gt;VARCHAR&lt;/code&gt; (variable-length text).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;VC256-VC*&lt;/strong&gt;, &lt;strong&gt;VR256-VR*&lt;/strong&gt;, &lt;strong&gt;VU256-VU*&lt;/strong&gt; → stored as &lt;code&gt;CHAR&lt;/code&gt; (because of size limits in the Informix driver).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: customer name
&lt;/h3&gt;

&lt;p&gt;Imagine a field &lt;code&gt;CUSTOMER.NAME&lt;/code&gt; defined as &lt;code&gt;C40&lt;/code&gt; in Uniface. The Informix connector will create this as &lt;code&gt;CHAR(40)&lt;/code&gt; in the database.&lt;/p&gt;

&lt;p&gt;If you change it later to &lt;code&gt;VC40&lt;/code&gt;, Uniface would map it to &lt;code&gt;VARCHAR(40)&lt;/code&gt;, which can save space but may behave differently in indexes and comparisons. So plan your character packing codes with your DBA rules in mind.&lt;/p&gt;




&lt;h2&gt;
  
  
  Numbers and money 💰
&lt;/h2&gt;

&lt;p&gt;For numeric fields, the Uniface packing code controls whether Informix uses &lt;code&gt;INTEGER&lt;/code&gt;, &lt;code&gt;SMALLINT&lt;/code&gt;, &lt;code&gt;DECIMAL&lt;/code&gt;, &lt;code&gt;FLOAT&lt;/code&gt; or &lt;code&gt;MONEY&lt;/code&gt;. This is important for precision and performance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;I1-I2&lt;/strong&gt; → &lt;code&gt;SMALLINT&lt;/code&gt; (small integers).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;I3-I4&lt;/strong&gt; → &lt;code&gt;INTEGER&lt;/code&gt; (normal integers, for example IDs or counters).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;I8&lt;/strong&gt; → &lt;code&gt;FLOAT&lt;/code&gt; (large numeric values stored as floating point).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;F&lt;/strong&gt; → &lt;code&gt;DECIMAL&lt;/code&gt; (fixed-point numeric, generic &lt;code&gt;F&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;F4&lt;/strong&gt; → &lt;code&gt;REAL&lt;/code&gt; (4-byte floating point).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;F8&lt;/strong&gt; → &lt;code&gt;FLOAT&lt;/code&gt; (8-byte floating point).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;M1-M4&lt;/strong&gt; → &lt;code&gt;MONEY&lt;/code&gt; (monetary values).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;N1-N32&lt;/strong&gt; → &lt;code&gt;DECIMAL&lt;/code&gt; (numeric with different sizes and precision).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;(N)C1-32&lt;/strong&gt; → &lt;code&gt;DECIMAL&lt;/code&gt; (numeric values packed with a &lt;code&gt;C&lt;/code&gt; packing, but stored as decimal).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;O1-O32&lt;/strong&gt;, &lt;strong&gt;P1-P16&lt;/strong&gt;, &lt;strong&gt;Q1-Q16&lt;/strong&gt; → &lt;code&gt;DECIMAL&lt;/code&gt; (different decimal ranges and precisions).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: invoice amount
&lt;/h3&gt;

&lt;p&gt;For an invoice amount, a typical choice in Uniface is &lt;code&gt;M2&lt;/code&gt; (money with 2 decimals). The Informix column will then be of type &lt;code&gt;MONEY&lt;/code&gt;, which keeps the decimal places stable and is easy to sum in SQL.&lt;/p&gt;

&lt;p&gt;If you used a floating type like &lt;code&gt;F8&lt;/code&gt; instead, Informix would store it as &lt;code&gt;FLOAT&lt;/code&gt;, which can introduce rounding issues for financial calculations. So for prices and totals, it is safer to use &lt;code&gt;M*&lt;/code&gt; or &lt;code&gt;N*&lt;/code&gt; (decimal) instead of &lt;code&gt;FLOAT&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dates and times ⏰
&lt;/h2&gt;

&lt;p&gt;Date and time fields have special mappings because Informix has dedicated date and datetime types. Using the correct packing code here makes your queries simpler and more efficient.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;D&lt;/strong&gt;, &lt;strong&gt;D1-D11&lt;/strong&gt; → &lt;code&gt;DATE&lt;/code&gt; (calendar date without time).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;E&lt;/strong&gt;, &lt;strong&gt;E1-E8&lt;/strong&gt;, &lt;strong&gt;E10&lt;/strong&gt; → &lt;code&gt;DATETIME YEAR TO SECOND&lt;/code&gt; (full date and time down to seconds).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;T3&lt;/strong&gt; → &lt;code&gt;DATETIME YEAR TO SECOND&lt;/code&gt; (time-related packing that maps to datetime).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: order date vs. timestamp
&lt;/h3&gt;

&lt;p&gt;For an &lt;code&gt;ORDER_DATE&lt;/code&gt; field, a simple &lt;code&gt;D&lt;/code&gt; is often enough and becomes &lt;code&gt;DATE&lt;/code&gt; in Informix. For an audit field like &lt;code&gt;LAST_UPDATE&lt;/code&gt;, you can use &lt;code&gt;E&lt;/code&gt; so that Informix stores &lt;code&gt;DATETIME YEAR TO SECOND&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This way you can easily select all rows from today or sort by the exact update time in SQL. It also keeps the storage compact and index-friendly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Serial, byte and text fields 📂
&lt;/h2&gt;

&lt;p&gt;Some Uniface packings are used for special Informix types like serial numbers, byte data and text data. These are important for technical IDs, blobs and large documentation fields.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;(S)A10&lt;/strong&gt; → &lt;code&gt;SERIAL&lt;/code&gt; (auto-increment integer, often used as technical primary key).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;SR1-SR*&lt;/strong&gt; → &lt;code&gt;BYTE&lt;/code&gt; (binary data, for example PDF or image stored as blob).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;SC1-SC*&lt;/strong&gt; → &lt;code&gt;TEXT&lt;/code&gt; (large text stored as a TEXT blob).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;SU1-SU*&lt;/strong&gt; → &lt;code&gt;TEXT&lt;/code&gt; (Unicode text stored in a TEXT-like way by the connector).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: document storage
&lt;/h3&gt;

&lt;p&gt;If you have a field &lt;code&gt;DOCUMENT.FILE_CONTENT&lt;/code&gt; with packing &lt;code&gt;SR1&lt;/code&gt;, Informix will store it as &lt;code&gt;BYTE&lt;/code&gt;. This is good for binary files like PDFs.&lt;/p&gt;

&lt;p&gt;For a field &lt;code&gt;DOCUMENT.LONG_COMMENT&lt;/code&gt; with packing &lt;code&gt;SC1&lt;/code&gt;, Informix will store it as &lt;code&gt;TEXT&lt;/code&gt;. This is better for long user comments or descriptions that can be larger than normal &lt;code&gt;VARCHAR&lt;/code&gt; limits.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this mapping matters in real projects 🧠
&lt;/h2&gt;

&lt;p&gt;The mapping between Uniface packing codes and Informix storage formats is not just a technical detail. It affects how indexes work, how much disk space you use and how easy it is to write SQL queries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If you choose a &lt;code&gt;CHAR&lt;/code&gt; packing for a field that changes a lot in length, your table may waste space and become slower.&lt;/li&gt;
&lt;li&gt;  If you choose a floating type (&lt;code&gt;F4&lt;/code&gt;, &lt;code&gt;F8&lt;/code&gt;, &lt;code&gt;I8&lt;/code&gt;) for monetary values, you may get rounding problems in reports.&lt;/li&gt;
&lt;li&gt;  If you use &lt;code&gt;TEXT&lt;/code&gt; or &lt;code&gt;BYTE&lt;/code&gt; for fields that you often filter in &lt;code&gt;WHERE&lt;/code&gt; clauses, you may not be able to index them easily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good practice is to create a small test table where you define one column for each packing code that you plan to use. Then you can check the real Informix types with tools like &lt;code&gt;dbschema&lt;/code&gt; or your favorite database browser and adjust your Uniface model before you go to production. ✅&lt;/p&gt;




&lt;p&gt;Uniface 10.4 and Informix give you a flexible and powerful combination for business applications. When you understand how packing codes map to Informix storage formats, you can design models that are both safe and efficient. 🚀&lt;/p&gt;

</description>
      <category>database</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Uniface 10.4 + Informix: Simple Guide to Stored Procedures 🚀</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Sun, 21 Dec 2025 06:58:31 +0000</pubDate>
      <link>https://forem.com/f345345dfg/uniface-104-informix-simple-guide-to-stored-procedures-3ogd</link>
      <guid>https://forem.com/f345345dfg/uniface-104-informix-simple-guide-to-stored-procedures-3ogd</guid>
      <description>&lt;p&gt;&lt;em&gt;🤖 This blog post was created with the help of an AI assistant and is based on the official Uniface 10.4 documentation for “Informix Stored Procedures”.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you build Uniface applications on Informix, performance matters. One simple way to speed up basic database operations is to use stored procedures generated by the Uniface Informix connector (INF).&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a stored procedure? 🤔
&lt;/h2&gt;

&lt;p&gt;A stored procedure is one or more SQL statements that are already parsed and compiled and stored in the Informix database. Because of this, Informix can execute them immediately without parsing the SQL text again each time.&lt;/p&gt;

&lt;p&gt;Compared to sending raw SQL from your application, stored procedures can be faster and more consistent for common operations.&lt;/p&gt;




&lt;h2&gt;
  
  
  How the INF connector uses stored procedures
&lt;/h2&gt;

&lt;p&gt;The INF connector can create stored procedures automatically when it creates the base tables in Informix. These procedures handle the most basic I/O operations: insert, fetch, update, delete, and select.&lt;/p&gt;

&lt;p&gt;To enable this behavior, you must set the &lt;code&gt;procs&lt;/code&gt; connector option in the Uniface assignment file for Informix. Without this option, Uniface does not create or use these Informix stored procedures.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stored procedures created by INF 🔧
&lt;/h2&gt;

&lt;p&gt;For each table (let’s call it &lt;code&gt;table_name&lt;/code&gt;), the connector can create several procedures with specific suffixes. Here are the most important ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;table_name_E&lt;/code&gt; – Existence check. This procedure checks if &lt;code&gt;table_name&lt;/code&gt; already has the expected procedures.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;table_name_I&lt;/code&gt; – Insert a row into &lt;code&gt;table_name&lt;/code&gt;. This one is &lt;strong&gt;not&lt;/strong&gt; created for tables that contain segmented fields.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;table_name_F&lt;/code&gt; – Fetch all nonsegmented fields in one row of &lt;code&gt;table_name&lt;/code&gt; using a specific primary key, and optionally lock the row.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;table_name_U&lt;/code&gt; – Update one row in &lt;code&gt;table_name&lt;/code&gt; based on the primary key, or the primary key plus the &lt;code&gt;U_VERSION&lt;/code&gt; field. This is also not created for tables that contain segmented fields.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;table_name_D&lt;/code&gt; – Delete a row in &lt;code&gt;table_name&lt;/code&gt; based on the primary key, or the primary key plus &lt;code&gt;U_VERSION&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;table_name_S&lt;/code&gt; – Select nonsegmented fields for all rows of &lt;code&gt;table_name&lt;/code&gt;, using a select cache for better performance.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;table_name_S#&lt;/code&gt; – Select nonsegmented fields using a specific index number &lt;code&gt;#&lt;/code&gt;, again using the select cache. The connector generates one stored procedure for each index that is used in such select operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, Uniface can generate extra stored procedures to enforce referential integrity, depending on your settings and table relationships.&lt;/p&gt;




&lt;h2&gt;
  
  
  Segmented fields and stored procedures 📦
&lt;/h2&gt;

&lt;p&gt;Informix supports segmented fields (for example, large text or byte data stored in separate locations). The INF connector has special rules for these fields.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The connector never uses stored procedures to manipulate segmented fields.&lt;/li&gt;
&lt;li&gt;  For tables that contain segmented fields, the connector does &lt;strong&gt;not&lt;/strong&gt; create the insert (&lt;code&gt;_I&lt;/code&gt;) or update (&lt;code&gt;_U&lt;/code&gt;) procedures.&lt;/li&gt;
&lt;li&gt;  The other procedures (&lt;code&gt;_F&lt;/code&gt;, &lt;code&gt;_D&lt;/code&gt;, &lt;code&gt;_S&lt;/code&gt;, &lt;code&gt;_S#&lt;/code&gt;) are still created but they only work with nonsegmented fields.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For read, write, and update operations that involve segmented fields, the connector falls back to dynamic SQL instead of using stored procedures.&lt;/p&gt;




&lt;h2&gt;
  
  
  Serial fields and the serial insert option 🔁
&lt;/h2&gt;

&lt;p&gt;Informix also supports serial fields (auto-increment numeric values). In Uniface, the behavior for tables with serial fields depends on the connector options.&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;serial insert&lt;/code&gt; option is turned on together with the &lt;code&gt;procs&lt;/code&gt; option, the INF connector changes its behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  For tables that contain serial fields, the connector does &lt;strong&gt;not&lt;/strong&gt; use the insert stored procedure.&lt;/li&gt;
&lt;li&gt;  Instead, it uses dynamic SQL to execute the write request, so that serial values are handled correctly.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Example: Simple customer table 🧑‍💻
&lt;/h2&gt;

&lt;p&gt;Let’s look at a small example. Imagine a table called &lt;code&gt;customer&lt;/code&gt; with a primary key &lt;code&gt;customer_id&lt;/code&gt;, no segmented fields, and no serial fields.&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;procs&lt;/code&gt; option enabled, you can expect the INF connector to create procedures like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;customer_I&lt;/code&gt; – Insert a new customer row.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;customer_F&lt;/code&gt; – Fetch one customer row by primary key (and optionally lock it).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;customer_U&lt;/code&gt; – Update an existing customer row using the primary key (and possibly &lt;code&gt;U_VERSION&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;customer_D&lt;/code&gt; – Delete a customer row using the primary key (and possibly &lt;code&gt;U_VERSION&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;customer_S&lt;/code&gt; – Select all customer rows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In your Uniface component, the connector can call these stored procedures internally when you do normal store, read, or update operations. You do not have to call the procedures manually; Uniface does it for you based on your configuration.&lt;/p&gt;




&lt;h2&gt;
  
  
  When should you enable stored procedures? 💡
&lt;/h2&gt;

&lt;p&gt;Using the &lt;code&gt;procs&lt;/code&gt; option makes most sense when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  You want better performance for common CRUD operations on Informix.&lt;/li&gt;
&lt;li&gt;  Your tables mainly use nonsegmented fields (or you are fine with dynamic SQL for the segmented ones).&lt;/li&gt;
&lt;li&gt;  You like a clear, predictable mapping between Uniface I/O and Informix stored procedures.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have many segmented fields or very complex SQL logic, you may still rely more on dynamic SQL or custom SQL statements. But for standard, frequent operations, the generated stored procedures are a clean and efficient solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts 😊
&lt;/h2&gt;

&lt;p&gt;Uniface 10.4 and Informix work well together when you use the INF connector options correctly. With the &lt;code&gt;procs&lt;/code&gt; option, you get a set of ready-made stored procedures that speed up basic I/O.&lt;/p&gt;

&lt;p&gt;Add in the special behavior for segmented and serial fields, and you have a flexible setup: fast where possible, dynamic where necessary.&lt;/p&gt;

&lt;p&gt;Happy coding with Uniface and Informix! 🚀&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>performance</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Uniface 10.4 + Informix: Simple Guide to DSQL Support 🧩</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Sun, 21 Dec 2025 06:55:17 +0000</pubDate>
      <link>https://forem.com/f345345dfg/uniface-104-informix-simple-guide-to-dsql-support-4ah5</link>
      <guid>https://forem.com/f345345dfg/uniface-104-informix-simple-guide-to-dsql-support-4ah5</guid>
      <description>&lt;p&gt;&lt;em&gt;🤖 This blog post was created with the help of an AI assistant and is based on the Uniface 10.4 documentation section “SQL Support on Informix”.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you use Uniface 10.4 with Informix, you can run direct SQL from your ProcScript code. The main tools for this are the &lt;code&gt;sql&lt;/code&gt; ProcScript command and the SQL Editor in the Uniface environment. 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  What is DSQL in Uniface?
&lt;/h2&gt;

&lt;p&gt;In this context, DSQL means that Uniface sends your SQL string directly to Informix. You write the SQL yourself, and it is executed on the Informix side without extra Uniface logic.&lt;/p&gt;

&lt;p&gt;You can use the &lt;code&gt;sql&lt;/code&gt; statement in ProcScript to execute SQL like &lt;code&gt;select&lt;/code&gt;, &lt;code&gt;insert&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, or &lt;code&gt;delete&lt;/code&gt;. You can also use the SQL Editor in Uniface to run SQL statements against your Informix database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring SQL in the message frame
&lt;/h2&gt;

&lt;p&gt;Uniface can show the SQL statements that are sent to Informix in the message frame. This can help you understand which SQL is actually executed.&lt;/p&gt;

&lt;p&gt;However, you cannot see the actual values used in these SQL statements. Only the statement itself is visible, not the concrete parameter values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Important rules for transactions
&lt;/h2&gt;

&lt;p&gt;For the single connection mechanism, you must not use &lt;code&gt;commit work&lt;/code&gt; or &lt;code&gt;rollback&lt;/code&gt; inside an SQL string that you send with the &lt;code&gt;sql&lt;/code&gt; instruction. The same restriction applies to SQL that you execute in SQL Edit.&lt;/p&gt;

&lt;p&gt;Uniface handles the single database connection and its transaction state. If you send &lt;code&gt;commit work&lt;/code&gt; or &lt;code&gt;rollback&lt;/code&gt; yourself, you can disturb this mechanism, so it should be avoided in this mode.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: what you should &lt;strong&gt;not&lt;/strong&gt; do
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; ❌ Bad example in single connection mode
sql "update customer set active = 1 where id = 100;
     commit work", "inf"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example mixes data change and transaction control in one SQL string and should not be used with the single connection mechanism.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better example without transaction control
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; ✅ Better example: let Uniface control the connection
sql "update customer set active = 1 where id = 100", "inf"

; Here, Uniface or your normal application flow decides when the work is committed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the SQL statement only updates data and does not send &lt;code&gt;commit work&lt;/code&gt; or &lt;code&gt;rollback&lt;/code&gt;, which fits the rule for the single connection mechanism.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using SQL Edit when you have no front-end
&lt;/h2&gt;

&lt;p&gt;Sometimes you do not have an Informix front-end and have not yet created an Informix database. In that situation, you cannot log on to Informix with another tool.&lt;/p&gt;

&lt;p&gt;In this case, you can use SQL Edit in Uniface to create the Informix database and run the required SQL statements. This gives you a way to work with Informix even if Uniface is your only available front-end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations with BLOB fields
&lt;/h2&gt;

&lt;p&gt;There is an important limitation for BLOB data when you use DSQL on Informix. You cannot select, insert, or update BLOB fields in SQL Edit or with the &lt;code&gt;sql&lt;/code&gt; instruction.&lt;/p&gt;

&lt;p&gt;If you need to work with BLOB fields, you must use other Uniface mechanisms instead of SQL Edit or the &lt;code&gt;sql&lt;/code&gt; command. This keeps your application compatible with the Informix driver limitations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: simple select without BLOB
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; ✅ Valid DSQL example (no BLOB involved)
sql/data "select id, name from document where status = 'A'", "inf"

if ($status &amp;gt;= 0)
  message "Select was successful."
else
  message "Select failed, status = %%$status"
endif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the SQL selects only normal fields like ID and NAME and does not touch any BLOB fields, so it is safe with the documented DSQL limitations.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use DSQL on Informix
&lt;/h2&gt;

&lt;p&gt;Use DSQL (the &lt;code&gt;sql&lt;/code&gt; instruction or SQL Edit) when you want to send your own SQL directly to Informix from Uniface. It is useful when you know the exact statement you want to execute.&lt;/p&gt;

&lt;p&gt;Do not use DSQL for BLOB operations and do not include &lt;code&gt;commit work&lt;/code&gt; or &lt;code&gt;rollback&lt;/code&gt; in your SQL when you work with the single connection mechanism. Following these rules keeps your Uniface and Informix integration stable and predictable.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;✍️ This article is a simplified explanation of the “SQL Support on Informix” section from the Uniface 10.4 documentation, written with AI assistance to make the topic easier to understand.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Uniface 10.4 + Informix: Simple Guide to Data Retrieval 📊</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Sun, 21 Dec 2025 06:52:07 +0000</pubDate>
      <link>https://forem.com/f345345dfg/uniface-104-informix-simple-guide-to-data-retrieval-pih</link>
      <guid>https://forem.com/f345345dfg/uniface-104-informix-simple-guide-to-data-retrieval-pih</guid>
      <description>&lt;p&gt;This article gives a simple overview of how data retrieval works when you use &lt;strong&gt;Uniface 10.4&lt;/strong&gt; with an &lt;strong&gt;Informix&lt;/strong&gt; database. 😊 This post was created with the help of an AI assistant and is based on the official Uniface 10.4 documentation about “Data Retrieval on Informix”.&lt;/p&gt;




&lt;h2&gt;
  
  
  read with where clause 🔍
&lt;/h2&gt;

&lt;p&gt;The Uniface &lt;code&gt;read&lt;/code&gt; statement can use a &lt;strong&gt;where&lt;/strong&gt; clause that Uniface inserts directly into the generated &lt;code&gt;select&lt;/code&gt; statement for Informix. Everything inside the double quotes of the where clause is copied as text into the SQL, so you must always write valid Informix syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trigger read read where "AMOUNT &amp;gt; 1000 AND STATUS = 'OPEN'" end 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, Uniface does not try to interpret the condition; it simply passes the where text to Informix, which then filters the rows. This is helpful if you want to use Informix-specific features, such as special functions or optimizer hints. 🧠&lt;/p&gt;




&lt;h2&gt;
  
  
  Using the option parameter ⚙️
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;option&lt;/code&gt; parameter of the &lt;code&gt;read&lt;/code&gt; statement lets you tune how Uniface and Informix retrieve data, so you can improve performance. You can use it to control things like the maximum number of hits (rows) that should be returned, the number of rows per fetch step, or how many hits are cached.&lt;/p&gt;

&lt;p&gt;Example (typical pattern):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trigger read read "ORDER" option "maxhits=500, stepsize=50, hitcache=100" end 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In simple words, this kind of setting can do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;maxhits=500&lt;/code&gt;: Stop after 500 rows, even if more rows exist.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;stepsize=50&lt;/code&gt;: Fetch data in blocks of 50 rows at a time.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;hitcache=100&lt;/code&gt;: Keep up to 100 hits in memory for faster navigation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exact option names and values are connector specific, but the idea of limiting rows and controlling fetch behavior is important for performance.&lt;/p&gt;




&lt;h2&gt;
  
  
  selectdb and count functions 🧮
&lt;/h2&gt;

&lt;p&gt;Informix always supports the &lt;code&gt;selectdb&lt;/code&gt; statement, but the way it behaves with &lt;code&gt;count&lt;/code&gt; and plain field transport can affect performance. If you use the &lt;code&gt;count&lt;/code&gt; function in a &lt;code&gt;selectdb&lt;/code&gt; that also lists several fields, Informix may perform a separate &lt;code&gt;select&lt;/code&gt; for every field named, and the same can happen if you use &lt;code&gt;selectdb&lt;/code&gt; without any aggregate functions at all.&lt;/p&gt;

&lt;p&gt;Pattern that can be slow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; Can cause extra selects per field selectdb (count(F1), max(F2), min(F3)) from MYTABLE to (CNT.DUMMY, MAXF2.DUMMY, MINF3.DUMMY) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; 1) Count in a separate selectdb selectdb (count(F1)) from MYTABLE to (CNT.DUMMY) ; 2) Other aggregates in a second selectdb selectdb (max(F2), min(F3), ave(F4), sum(F5)) from MYTABLE to (MAXF2.DUMMY, MINF3.DUMMY, AVGF4.DUMMY, SUMF5.DUMMY) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By separating &lt;code&gt;count&lt;/code&gt; (and simple transport without aggregate) from the other aggregate functions, you avoid unnecessary extra selects and keep your application faster and more scalable. 🚀&lt;/p&gt;




&lt;h2&gt;
  
  
  Field subsetting on Informix 🧩
&lt;/h2&gt;

&lt;p&gt;Uniface can automatically &lt;strong&gt;subset fields&lt;/strong&gt; when working with Informix, but only in specific environments. Fields that are not painted on the form and not mentioned in ProcScript are then not selected, fetched, inserted, or updated by the Informix connector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important rules:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Field subsetting is allowed only for &lt;strong&gt;Informix OnLine&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Field subsetting is &lt;strong&gt;not&lt;/strong&gt; allowed for &lt;strong&gt;Informix Standard Engine (SE)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example scenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Your table has 20 columns.&lt;/li&gt;
&lt;li&gt;  Your Uniface form only shows 5 fields and your ProcScript also uses only these 5.&lt;/li&gt;
&lt;li&gt;  The connector will then work only with these 5 fields and ignore the other 15, which reduces network traffic and improves performance. 📉&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Uniface kernel decides which fields are required and which fields can be skipped, so you do not need to configure this manually.&lt;/p&gt;




&lt;h2&gt;
  
  
  Maximum number of open cursors 🎫
&lt;/h2&gt;

&lt;p&gt;The Informix connector in Uniface supports up to &lt;strong&gt;256 open cursors&lt;/strong&gt;. An open cursor is basically an active query on the database, so every hitlist or running query can use one cursor.&lt;/p&gt;

&lt;p&gt;What this means for your application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If you open many hitlists or nested queries and never close them, you can reach the cursor limit.&lt;/li&gt;
&lt;li&gt;  You should close or release hitlists and instances when you no longer need them, especially in long-running components or batch jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keeping an eye on cursor usage helps you avoid “too many open cursors” errors and keeps your Uniface and Informix system stable. ⚠️&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical mini example 🧪
&lt;/h2&gt;

&lt;p&gt;Here is a small example that combines several of these ideas in one trigger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trigger read ; 1) Read orders with a limit and tuned fetch behavior read "ORDER" option "maxhits=200, stepsize=20" ; 2) Read only recent orders using an Informix-specific where clause read where "ORDER_DATE &amp;gt;= TODAY - 30" option "maxhits=100" ; 3) Get total number of orders selectdb (count(ORDER_ID)) from ORDER to (CNT.DUMMY) ; 4) Get average order amount in a separate selectdb selectdb (ave(AMOUNT)) from ORDER to (AVGAMOUNT.DUMMY) end 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two &lt;code&gt;read&lt;/code&gt; statements show how you can combine where clauses and options to limit hits and tune performance. The pair of &lt;code&gt;selectdb&lt;/code&gt; statements shows the recommended way to separate &lt;code&gt;count&lt;/code&gt; from other aggregates to avoid extra selects and keep Informix efficient. 💡&lt;/p&gt;

&lt;p&gt;With these patterns, your Uniface 10.4 applications can retrieve data from Informix in a way that is both simple to understand and friendly to database performance. 🚀&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>informix</category>
      <category>dataretrieval</category>
      <category>performance</category>
    </item>
    <item>
      <title>Uniface 10.4 and Informix: Simple Guide to Transaction Control 💾</title>
      <dc:creator>Franz</dc:creator>
      <pubDate>Sun, 21 Dec 2025 06:46:34 +0000</pubDate>
      <link>https://forem.com/f345345dfg/uniface-104-and-informix-simple-guide-to-transaction-control-4gf2</link>
      <guid>https://forem.com/f345345dfg/uniface-104-and-informix-simple-guide-to-transaction-control-4gf2</guid>
      <description>&lt;p&gt;This article gives a simple overview of how &lt;strong&gt;transaction control&lt;/strong&gt; works when you use Uniface 10.4 with an Informix database. 😊&lt;br&gt;&lt;br&gt;
This post was created with the help of an AI assistant and is based on the official Uniface 10.4 documentation about “Transaction Control on Informix”.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why transactions matter 💡
&lt;/h2&gt;

&lt;p&gt;Transactions help you keep your data consistent.&lt;br&gt;&lt;br&gt;
Either all changes are saved, or none of them are saved, which is very important in financial, medical, or other critical systems.&lt;/p&gt;

&lt;p&gt;A typical example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  You insert an order into an &lt;code&gt;ORDERS&lt;/code&gt; table.&lt;/li&gt;
&lt;li&gt;  You insert order lines into an &lt;code&gt;ORDER_LINES&lt;/code&gt; table.&lt;/li&gt;
&lt;li&gt;  You update the customer’s credit balance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these actions should be part of &lt;strong&gt;one&lt;/strong&gt; transaction. If something fails, you want to roll back everything.&lt;/p&gt;
&lt;h2&gt;
  
  
  Transaction logging in Informix 🧱
&lt;/h2&gt;

&lt;p&gt;Informix can work with or without &lt;strong&gt;transaction logging&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If there is &lt;strong&gt;no transaction logging&lt;/strong&gt;, the database does not manage transactions in a way that supports safe &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;rollback&lt;/code&gt; operations; changes are effectively written without the option of a full transactional rollback.&lt;/li&gt;
&lt;li&gt;  If &lt;strong&gt;transaction logging is enabled&lt;/strong&gt;, Informix supports both &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;rollback&lt;/code&gt;, so Uniface can use transactions safely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, if you want real transaction control, make sure that logging is turned on for your Informix database.&lt;/p&gt;
&lt;h2&gt;
  
  
  Never commit inside SQL strings 🚫
&lt;/h2&gt;

&lt;p&gt;Uniface lets you send SQL directly using the &lt;code&gt;sql&lt;/code&gt; ProcScript statement.&lt;br&gt;&lt;br&gt;
However, you must &lt;strong&gt;not&lt;/strong&gt; put &lt;code&gt;commit&lt;/code&gt; or &lt;code&gt;rollback&lt;/code&gt; into the SQL string when you use the &lt;strong&gt;single connection mechanism&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  In the single connection mechanism, a logon path can be shared by multiple logical paths.&lt;/li&gt;
&lt;li&gt;  If you end a transaction on that logon path, you end the transaction for &lt;strong&gt;all&lt;/strong&gt; paths that use the same connector.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example of what &lt;strong&gt;not&lt;/strong&gt; to do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; ❌ bad practice in single connection sql "update orders set status = 'PAID' where order_id = 123" sql "commit" 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better: keep your business SQL and your transaction control separate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; ✅ better: let Uniface control the transaction sql "update orders set status = 'PAID' where order_id = 123" if ($status &amp;gt;= 0) commit ; Uniface commit else rollback ; Uniface rollback endif 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this version, Uniface manages the transaction on the logon path correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple connections vs. global transactions 🔀
&lt;/h2&gt;

&lt;p&gt;Uniface and Informix also support a &lt;strong&gt;multiple connection mechanism&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
In this mode, you can have several open connections, and each connection has its &lt;strong&gt;own&lt;/strong&gt; transaction.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Multiple concurrent transactions are supported: each connection can start, commit, and roll back its own transaction.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Global transactions&lt;/strong&gt;, where a single transaction spans several databases over multiple connections, are not supported by Informix as a native feature in this Uniface connector context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example scenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Connection A uses database &lt;code&gt;FINANCE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Connection B uses database &lt;code&gt;LOGGING&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Start a transaction on A, do some updates, and commit A.&lt;/li&gt;
&lt;li&gt;  Start a transaction on B, do other updates, and roll back B.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But you cannot have one atomic transaction that covers both &lt;code&gt;FINANCE&lt;/code&gt; and &lt;code&gt;LOGGING&lt;/code&gt; at the same time just by using normal Informix transactions; for real distributed transactions you need a transaction manager and XA support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two-phase commit support ✅
&lt;/h2&gt;

&lt;p&gt;Informix supports &lt;strong&gt;Two-Phase Commit (2PC)&lt;/strong&gt; for XA-compliant environments, and this is handled largely &lt;strong&gt;transparently&lt;/strong&gt; by the database and the transaction manager.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Two-Phase Commit is a protocol used to make sure that a distributed transaction either commits everywhere or rolls back everywhere.&lt;/li&gt;
&lt;li&gt;  In a setup with a transaction manager, Informix takes part in this process, while Uniface still uses its usual &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;rollback&lt;/code&gt; ProcScript statements to signal transaction boundaries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important point: you do not need special &lt;code&gt;commit&lt;/code&gt; SQL statements inside your Uniface SQL strings to “enable” 2PC; the infrastructure around Informix handles that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple practical tips 🧰
&lt;/h2&gt;

&lt;p&gt;Here are some simple rules you can follow in daily work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Make sure &lt;strong&gt;transaction logging&lt;/strong&gt; is enabled if you need safe &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;rollback&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Do &lt;strong&gt;not&lt;/strong&gt; put &lt;code&gt;commit&lt;/code&gt; or &lt;code&gt;rollback&lt;/code&gt; inside SQL strings when using the single connection mechanism; use Uniface’s &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;rollback&lt;/code&gt; instead.&lt;/li&gt;
&lt;li&gt;  When using multiple connections, remember that each connection has its own transaction, and Informix does not provide one global transaction across several databases in this setup.&lt;/li&gt;
&lt;li&gt;  If your environment uses Two-Phase Commit, let Informix and the transaction manager do the heavy lifting; keep your Uniface code clean and simple.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these rules, your Uniface 10.4 applications can use Informix transactions in a safe and predictable way. 🚀&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>informix</category>
      <category>transactions</category>
      <category>database</category>
    </item>
  </channel>
</rss>
