3.1. Project structure
An OrmFactory project is a model of one or more databases together with the information used to work with, visualize, and generate code from that model.
The project structure can be viewed and managed in the Project Explorer.
The logical project structure looks roughly like this:
Project
├── Database
│ └── Schema
│ └── Table
│ ├── Column
│ ├── PrimaryKey
│ ├── ForeignKey
│ ├── VirtualForeignKey
│ ├── Index
│ ├── Unique
│ ├── Parameter
│ └── NamedRows
├── Layout
├── Connection
├── Generator
└── Profile
The database, schema, and table hierarchy represents the database model itself. The other objects provide additional project-level information around that model.
Database Structure
A Database is a logical database unit within the project. It represents a database model together with the database-specific settings associated with that model.
Each Database is associated with exactly one Connection, and each Connection is associated with one Database. The Database defines what the database contains; the Connection defines how OrmFactory connects to it.
A Database may contain one or more schemas:
<Database Name="Schemas" Type="MySql"> <Schema Name="erp"> ... </Schema> </Database>
The Type identifies the database system, such as MySQL, PostgreSQL, SQL Server, or Oracle.
A database may also define a Migration generator. This identifies the generator used for producing database migration output for that database.
<Database Name="Schemas" Type="MySql"> <MigrationGenerator Filename="migrations.py" /> ... </Database>
Schema
A Schema groups tables within a database.
<Schema Name="erp" Comment="ERP tables"> ... </Schema>
A schema has a name and may have a comment.
Table
A Table represents a database table.
<Table Name="ReleaseFiles" ClassName="ReleaseFile" RepositoryName="ReleaseFiles"> ... </Table>
The table name is the actual database table name. OrmFactory does not automatically change it when generating code.
A table may also contain names used by generators:
ClassName— the class name generated for the table.RepositoryName— the repository name generated for the table.
These values are part of the project model and can be modified independently of the database table name.
A table may also have:
- a comment;
- an
Ignoreflag; - columns;
- a primary key;
- foreign keys;
- virtual foreign keys;
- indexes;
- unique constraints;
- parameters;
- named rows.
Columns
A Column represents a table column.
<Column Name="VersionId" Type="int" FieldName="VersionId" Nullable="true" />
The Name is the database column name.
FieldName is the name used by generators when representing the column in generated code.
Other column properties include:
- database type;
- comment;
- default value;
- default constraint name;
- nullability;
- auto-increment;
OnUpdateCurrentTimestamp;Ignore;- custom parameters.
For example:
<Column Name="CreatedDate" Type="datetime" FieldName="CreatedDate" Default="current_timestamp()" />
The database name and generated field name are independent. A generator may transform FieldName according to its configured naming style.
Primary Keys
A table may have one PrimaryKey.
<PrimaryKey Name="PK_ReleaseFiles" Columns="Id" />
A primary key contains its name and the columns participating in the key.
Composite primary keys are represented by multiple column names in Columns.
Foreign Keys
A ForeignKey describes a relationship from one table to another.
<ForeignKey Name="FK_VersionId_Versions_Id" FromColumn="VersionId" ToTable="Versions" ToColumn="Id" FieldName="Version" ReverseFieldName="ReleaseFiles" />
The relationship specifies:
- the foreign key name;
- the source column;
- the target table;
- the target column;
- optionally the target schema;
- generated field names for both sides of the relationship;
- delete and update actions.
ToSchema is only required when the referenced table belongs to a different schema.
For example:
<ForeignKey Name="FK_Order_Customer" FromColumn="CustomerId" ToTable="Customer" ToColumn="Id" ToSchema="crm" />
FieldName and ReverseFieldName provide names for generated accessors. They do not change the database relationship itself.
Virtual Foreign Keys
A VirtualForeignKey has the same relationship information as a foreign key but does not necessarily correspond to a physical database constraint.
<VirtualForeignKey Name="FK_Orders_Users" FromColumn="UserId" ToTable="Users" ToColumn="Id" />
Virtual foreign keys are useful when the relationship is known to the application or project but is not represented by an actual foreign key constraint in the database.
Indexes
An Index describes a database index.
<Index Name="IX_Orders_CreatedDate" Columns="CreatedDate" />
Indexes may contain multiple columns and may be marked as unique.
<Index Name="IX_Orders_Number" Columns="Number,Year" Unique="true" />
Unique Constraints
A Unique represents a unique constraint.
<Unique Name="UQ_Users_Email" Columns="Email" />
As with indexes and primary keys, multiple columns can participate in the constraint.
Parameters
Tables and columns may contain Parameter objects.
<Parameter Name="SomeOption" Value="SomeValue" />
Parameters are arbitrary key-value metadata associated with the model element. They can be used by generators or other project functionality that needs additional information not represented by the standard model properties.
Named Rows
A table may define Named Rows.
<NamedRows NameColumn="Name" Columns="Id,Name,Code" />
Named Rows describe data that can be associated with generated code by using values from selected database rows.
They are model metadata rather than additional database objects.
Layouts
A Layout is a visual representation of the database model.
A layout contains references to tables and their positions on the diagram:
<Layout Name="Product"> <Table Name="erp.Orders" Database="Schemas" Point="-145,784" /> <Table Name="erp.Customers" Database="Schemas" Point="320,784" /> </Layout>
The <Table> elements inside a layout do not define new tables. They reference tables already present in the project model.
A layout therefore belongs to the project, but is separate from the database hierarchy.
A project may contain multiple layouts showing the same model in different ways.
Connections
A Connection describes how OrmFactory connects to a database.
Connections are project-level resources and can be reused by profiles.
A connection contains common connection properties such as:
- database type;
- server host;
- server port;
- user name;
- password;
- database name;
- optional SSH connection information.
Some database types have additional connection properties. For example, SQL Server and O-Bridge connections have their own additional settings.
A connection does not define the database model. It only describes how to access a database.
Generators
A Generator defines a code-generation configuration.
<Generator Name="Python" Type="Python" Filename="generator.py" NameStyle="CamelCase"> ... </Generator>
A generator can specify:
- generator type;
- generator script or executable;
- naming style;
- generator arguments;
- optional partial-generation settings.
Partial Generation
A generator may restrict generation to selected parts of the project.
<PartialGeneration WholeProject="false"> <Database Name="Schemas" Include="true"> <Schema Name="erp" Include="true"> <Table Name="Orders" /> <Table Name="Customers" /> </Schema> </Database> </PartialGeneration>
These elements select existing databases, schemas, and tables. They do not create copies of those objects.
For example, the following table:
<Table Name="Orders" />
inside PartialGeneration refers to the existing Orders table in the project model.
Profiles
A Profile associates databases with connections and can provide schema mappings.
<Profile Name="local"> <Database Name="Schemas" Connection="local"> <Schema Name="erp" MappedName="erp_local" /> </Database> </Profile>
A profile is useful when the same logical project needs to be used with different database environments.
For example, a project may contain a Schemas database model while different profiles specify different connections for local, staging, and production environments.
A profile does not contain another copy of the database model. It references the project's existing databases and connections.
Complete Example
A simplified project can therefore look like this:
<Project Name="0f" Software="ormfactory.com"> <Database Name="Schemas" Type="MySql"> <Schema Name="erp"> <Table Name="Orders" ClassName="Order" RepositoryName="Orders"> <Column Name="Id" Type="int" FieldName="Id" AutoIncrement="true" Nullable="false" /> <Column Name="CustomerId" Type="int" FieldName="CustomerId" /> <PrimaryKey Name="PK_Orders" Columns="Id" /> <ForeignKey Name="FK_Orders_Customers" FromColumn="CustomerId" ToTable="Customers" ToColumn="Id" FieldName="Customer" /> </Table> </Schema> </Database> <Connection Name="local"> ... </Connection> <Generator Name="Python" Type="Python" Filename="generator.py" /> <Layout Name="Main"> <Table Name="erp.Orders" Database="Schemas" Point="100,100" /> </Layout> <Profile Name="local"> <Database Name="Schemas" Connection="local" /> </Profile> </Project>
The important distinction is that the project contains two kinds of information:
- Database model — databases, schemas, tables, columns, keys, indexes, and related metadata.
- Project resources and configuration — layouts, connections, generators, and profiles.
All of these belong to the same logical project, regardless of how the project is stored on disk.