Elastic Database Reference
Hierarchical object database with built-in DSL
Overview
The Elastic Database is a hierarchical object database where:
- Objects (class instances) are stored directly in the database
- Collections are named containers holding objects of a type
- Subcollections are nested within objects via LIST members
- CID (Collection ID) uniquely identifies each collection
- OID (Object ID) uniquely identifies each object within a collection
Hierarchy Structure
Database Root
├── Collection: Users (CID: 1)
│ ├── Object: TT_User (OID: 1)
│ │ ├── Fields: Type, Login, Email...
│ │ ├── Subcollection: Orgs (links)
│ │ └── Subcollection: Projects
│ │ └── Object: TT_Project
│ │ └── Subcollection: Tasks
│ └── Object: TT_User (OID: 2)
│
├── Collection: Orgs (CID: 2)
│ └── Object: TT_Org (OID: 1)
│ ├── Fields: Name, AdminOid...
│ ├── Subcollection: Users (member links)
│ └── Subcollection: Partitions
Schema Definition
The database schema is defined declaratively through class annotations:
// Main collection class - creates "Users" collection
class attrib(db_col, Users) TT_User : public SB_User {
public:
variant attrib(db, d_DWORD) Type; // Field: 32-bit int
variant attrib(db, d_string) Login; // Field: string
variant attrib(db, d_string) Email; // Field: string
variant attrib(db, LIST) Orgs; // Subcollection
variant attrib(db, LIST) Projects; // Subcollection
variant attrib(db, BINARY) Avatar; // Binary data
}
// Another main collection - creates "Orgs" collection
class attrib(db_col, Orgs) TT_Org {
public:
variant attrib(db, d_string) Name; // Field
variant attrib(db, d_DWORD) AdminOid; // Reference to user
variant attrib(db, LIST) Users; // Subcollection (members)
variant attrib(db, LIST) Partitions; // Subcollection
}
// Embedded class (no db_col - stored in LIST subcollections)
class TT_Project : public SB_Object {
variant attrib(db, d_string) Name;
variant attrib(db, LIST) Tasks; // Sub-subcollection
}
Field Attributes
| Attribute | Description |
|---|---|
attrib(db_col, Name) | Class-level: binds class to main collection |
attrib(db, d_DWORD) | 32-bit unsigned integer field |
attrib(db, d_QWORD) | 64-bit unsigned integer field |
attrib(db, d_string) | String field |
attrib(db, LIST) | Subcollection (nested objects) |
attrib(db, BINARY) | Binary data field |
Reference Attributes
For linking objects across collections:
// Paired reference (CID + OID to another object)
variant attrib(db_ref_cid, Users) UserCid;
variant attrib(db_ref_oid, Users) UserOid;
// Reference to OID in a global/main collection
variant attrib(db_glob_ref, Users) UserOid;
// Reference to just a collection CID
variant attrib(db_col_ref) CollectionCid;
Control Object
Every collection has a control object at obj_id=1 (class SB_Control):
class SB_Control {
variant attrib(db, d_DWORD) LastOid; // Last object ID
variant attrib(db, d_DWORD) OwnerCid; // Parent collection
variant attrib(db, d_DWORD) OwnerOid; // Owner object
variant attrib(db, LIST) SecondColCid; // Child collections
}
Query DSL
EPL has an embedded DSL for database operations inside elastic{} blocks:
SELECT
variant Obj, Cids, Oids, Err;
// By collection name
elastic{
SELECT obj: obj1 FROM Users WHERE Login="admin"
TO &Obj CID_OUT &Cids OID_OUT &Oids ERR_OUT &Err;
}
// By collection ID
elastic{
SELECT obj: obj1 FROM cid:<Cid> WHERE obj_id=<id> TO &Obj;
}
// Access subcollection
elastic{
SELECT obj: obj1 FROM cid:<Cid>.oid:<Oid>.mm:Projects TO &Obj;
}
INSERT
variant Obj = NewObject;
variant Cids, Oids, Err;
elastic{
INSERT <ClassName> INTO cid:<Cid> OBJECT &Obj
CID_OUT &Cids OID_OUT &Oids WAIT_FOR_END ERR_OUT &Err;
}
// Into subcollection
elastic{
INSERT TT_Project INTO cid:<Cid>.oid:<Oid>.mm:Projects
OBJECT &Obj OID_OUT &Oids WAIT_FOR_END;
}
UPDATE
variant Obj = ModifiedObject;
variant Err;
elastic{
UPDATE cid:<Cid> SET OBJECT &Obj WHERE obj_id=<oid> ERR_OUT &Err;
}
// No transaction mode
elastic{
UPDATE cid:<Cid> SET OBJECT &Obj WHERE obj_id=<oid> NO_TRANS ERR_OUT &Err;
}
// Update specific fields
elastic{
UPDATE cid:<Cid> SET Name="NewName", Status=1 WHERE obj_id=<oid>;
}
CREATE COLLECTION / SUBCOLLECTION
// Create main collection
elastic{
CREATE COLLECTION Users;
}
// Create subcollection
elastic{
CREATE SUBCOLLECTION cid:<ParentCid>.oid:<ParentOid>.mm:Projects
CID_OUT &Cids ERR_OUT &Err;
}
CREATE TEMPLATE
// Define object schema
elastic{
CREATE TEMPLATE TT_User, DWORD, Type, string, Login, string, Email, LIST, Projects;
}
Other Commands
// Show collections
elastic{ SHOW COLLECTIONS TO &Output; }
// Show templates
elastic{ SHOW TEMPLATES TO &Output; }
// Delete object
elastic{ DELETE FROM cid:<Cid> WHERE obj_id=<Oid>; }
// Binary data access
elastic{ OPEN_BIN cid:<Cid>.oid:<Oid>.mm:Avatar TO &hFile; }
elastic{ CLOSE_BIN <hFile>; }
Database Creation with TDbProcessor
include_file "$Studio/Sys/TDbProcessor.epl";
TDbProcessor @Proc;
Proc->DirTo = GetCurScriptDir() . "/";
Proc->ClassDir[0] = Proc->DirTo . "Classes/";
Proc->Path = GetCurScriptDir() . "/main.orn";
Proc->Create(); // Scans classes, creates collections & templates
TDbProcessor performs:
- Scans class directories for
.eplfiles - Reads
attrib(db_col, Name)→ Creates main collections - Reads
attrib(db, type)→ Creates templates (field schemas) - Executes
CREATE COLLECTIONandCREATE TEMPLATEcommands