Datasets Engine (Reference) manages database interactions, query execution, and data synchronization within the FrameworX runtime environment.
Advanced Topic: This document provides deep technical insight into the Dataset module execution engine. Most solutions don't require this level of understanding - the default engine behavior handles typical database operations automatically.
On this page:
The Dataset Engine manages all database operations through a multi-layered architecture that ensures security, performance, and scalability. This reference covers essential practices for production deployments, including concurrency management, security hardening, and performance optimization.
The engine orchestrates:
Understanding the engine helps when:
The Dataset Module operates through a distributed architecture:
TRunModule.exe (Dataset) handles:
TServer provides:
This separation enables secure database access through controlled gateways and maintains network security policies.
Single Thread per DB:
Parallel Execution Strategy: For concurrent operations to the same database, create multiple DB connections:
DB1 → Production Database (Thread 1)
DB2 → Production Database (Thread 2)
DB3 → Production Database (Thread 3)
Trigger: Property changes (Select, Insert, Update, Delete)
Flow:
Advantages:
Use Cases:
Trigger: Method calls (SelectCommand, ExecuteCommand)
Flow:
Advantages:
Risks:
Use Cases:
Tag mapping occurs in the original call domain:
Client-Initiated Calls:
Server-Initiated Calls:
Requirement | Domain | Example |
---|---|---|
User-specific data | Client | Personal preferences |
Shared data | Server | Production values |
Session data | Client | Login information |
Global state | Server | System status |
All Dataset Module properties exist in the server domain, creating shared resource risks:
Example Risk:
1. Client A sets: SQLStatement = "SELECT * FROM Orders WHERE Status='Open'"
2. Client B sets: SQLStatement = "SELECT * FROM Orders WHERE Status='Closed'"
3. Execute command runs with Client B's statement (last write wins)
Prevention Strategies:
Pattern 1: Direct Script Processing
csharp
DataTable result = @Dataset.Query.Query1.SelectCommand();
// Process data locally without server domain impact
foreach(DataRow row in result.Rows) {
// Local processing
}
Pattern 2: Tag Distribution
csharp
// Assign to DataTable tag for module sharing
@Tag.MyDataTable = @Dataset.Query.Query1.SelectCommand();
// Now available to displays, reports, etc.
Pattern 3: Mapped Navigation
csharp
// Configure mapping, then navigate rows
@Dataset.Query.Query1.Select();
@Dataset.Query.Query1.Next(); // Moves to next row
Control Data Volume:
Resource Planning:
Small Query: < 1,000 rows = Minimal impact
Medium Query: 1,000-10,000 rows = Monitor memory usage
Large Query: > 10,000 rows = Implement pagination
Never Do This:
sql
string query = "SELECT * FROM Users WHERE Name = '" + userInput + "'";
Always Do This:
sql
execute GetUserData @userName={Tag.UserInput}, @userId={Tag.UserId}
The platform's parameterization:
Gateway Configuration for Restricted Databases:
Benefits:
Database | Syntax Example | Special Considerations |
---|---|---|
SQL Server | SELECT TOP 10 * FROM Table | Use TOP for limiting |
SQLite | SELECT * FROM Table LIMIT 10 | Use LIMIT clause |
MySQL | SELECT * FROM \ Table` LIMIT 10` | Backticks for names |
PostgreSQL | SELECT * FROM "Table" LIMIT 10 | Case-sensitive names |
Oracle | SELECT * FROM Table WHERE ROWNUM <= 10 | ROWNUM for limiting |
Default Behavior:
Configuring External Databases:
DateTimeMode Settings:
- UTC: No conversion needed
- LocalTime: Platform converts automatically
- Custom: Handle in SQL statements
Local Time Queries:
sql
-- Adjust for local time zone (example: EST -5 hours)
WHERE Timestamp >= DATEADD(hour, -5, @Tag.StartTimeUTC)
? Indexes: Ensure indexes on filtered and joined columns ? Statistics: Update database statistics regularly ? Query Plans: Review execution plans for bottlenecks ? Connection Pooling: Enable for frequent operations ? Batch Operations: Group multiple operations when possible
Key Metrics to Track:
Diagnostic Properties:
@Dataset.Query.Query1.Error // Last error message
@Dataset.Query.Query1.ExecutionTime // Query duration
@Dataset.Query.Query1.RowCount // Result size
Good: Asynchronous from screen
csharp
@Dataset.Table.MyTable.SelectCommand = "SELECT * FROM Data";
Bad: Synchronous from screen (blocks UI)
csharp
@Dataset.Table.MyTable.SelectCommandWithStatus();
Method 1: Property Monitoring
csharp
@Dataset.Query.Query1.SelectCommand();
if (@Dataset.Query.Query1.Error != "") {
// Handle error
}
Method 2: Status Methods
csharp
string status;
DataTable result = @Dataset.Query.Query1.SelectCommandWithStatusAsync(out status);
if (status != "OK") {
// Handle error
}
Error Type | Typical Cause | Resolution |
---|---|---|
Connection Timeout | Network issues, server load | Increase timeout, check connectivity |
Syntax Error | Database-specific SQL | Verify syntax for target database |
Permission Denied | Insufficient privileges | Check database user permissions |
Deadlock | Concurrent transactions | Implement retry logic |
Out of Memory | Large result set | Add pagination, increase resources |
Option 1: Command Line Backup
bash
sqlite3 source.db ".backup backup.db"
Option 2: Online Backup API
Option 3: File System Copy
The Store & Forward feature has specific requirements:
For Store & Forward configuration, see Historian Archiving Process documentation.
Before deploying to production:
? Parameterized all dynamic queries ? Implemented error handling for all operations ? Tested concurrent access scenarios ? Configured appropriate timeouts ? Established backup procedures ? Documented recovery processes ? Verified timezone handling ? Optimized query performance ? Planned for data growth ? Secured network access
Slow queries:
Connection issues:
Tag mapping problems:
Thread blocking: