Data Models and ORM
Relevant source files
The following files were used as context for generating this wiki page:
Data Models and Object-Relational Mapping (ORM) in Casdoor provide the foundational structure for managing identity and access data. The system utilizes the XORM framework to abstract database operations, allowing the application to interface with various database backends such as MySQL, PostgreSQL, SQL Server, and SQLite while maintaining a consistent set of Go structures for business logic.
The core of this system resides in the object package, where the Ormer struct manages database connections and table synchronization. This architecture ensures that data persistence remains decoupled from the service layer, facilitating features like automated database initialization and data synchronization across disparate sources.
ORM Architecture and Driver Support
Casdoor employs a centralized ORM manager through the Ormer structure. This component is responsible for initializing database adapters, handling connection pools, and ensuring that the database schema matches the application's data models via synchronization methods.
The diagram above illustrates the initialization flow from configuration loading to database table synchronization.
Sources: object/ormer.go:40-85, object/ormer.go:217-336
The Ormer Component
The Ormer structure acts as a wrapper around the sql.DB connection and the xorm.Engine. It manages the lifecycle of database connections and provides a constructor NewAdapter that sets a finalizer for clean resource release.
| Field | Type | Description |
|---|---|---|
driverName | string | The name of the database driver (e.g., "mysql", "postgres"). |
dataSourceName | string | Connection string for the database. |
dbName | string | The specific database name to use. |
Db | *sql.DB | Standard Go SQL database connection. |
Engine | *xorm.Engine | The XORM engine for object-relational mapping. |
Sources: object/ormer.go:121-127, object/ormer.go:142-159
Data Synchronization and Initialization
Casdoor supports complex data initialization workflows, enabling the system to populate initial records from files or synchronize data from external databases.
Database Initialization
During startup, the system can automatically create databases and tables. For PostgreSQL, specialized logic in createDatabaseForPostgres handles schema creation and search path configuration. The Engine.Sync2 method is called for over 30 internal models to ensure the schema is up-to-date.
The sequence diagram shows how Casdoor ensures the physical database schema matches the internal Go structures.
Sources: object/ormer.go:107-118, object/ormer.go:183-215, object/ormer.go:234-336
Initialization from File
The InitFromFile function in object/init_data.go allows loading a comprehensive state from a JSON file. This is used for seeding the database with Organizations, Applications, Users, and Permissions.
| Model Category | Initialization Function | Logic Description |
|---|---|---|
| Organization | initDefinedOrganization | Checks existence; deletes old if not initDataNewOnly. |
| User | initDefinedUser | Generates unique ID and adds properties. |
| Enforcer | initDefinedEnforcer | Initializes enforcer and adds/saves policies. |
| Role/Permission | initDefinedRole/Permission | Populates RBAC structures. |
Sources: object/init_data.go:45-103, object/init_data.go:204-450
Casbin Access Models
A specific subset of the data models is dedicated to access control configuration, based on the Casbin framework. The Model struct represents a Casbin access control model.
The Model Structure
The Model struct persists the text-based definition of an access control model (e.g., RBAC, ABAC).
| Field | XORM Tag | JSON Key | Description |
|---|---|---|---|
Owner | varchar(100) notnull pk | owner | The organization that owns this model. |
Name | varchar(100) notnull pk | name | Unique name of the model. |
CreatedTime | varchar(100) | createdTime | Timestamp of creation. |
ModelText | mediumtext | modelText | The raw Casbin model definition string. |
Sources: object/model.go:27-36
Model Triggers and Checks
When a model's name is updated, a modelChangeTrigger is executed within a database transaction. This trigger updates references in both Permission and Enforcer tables to maintain referential integrity. Additionally, UpdateModelWithCheck validates the grammar of the ModelText using the Casbin library before persisting it.
Sources: object/model.go:102-124, object/model.go:138-167
Schema and API Definition
The data models are exposed via a RESTful API, defined in the project's Swagger documentation. Each ORM-mapped structure has a corresponding definition in the API layer.
This ER diagram represents the high-level relationships between key data models found in the system schema.
Sources: swagger/swagger.json:definitions, object/ormer.go:234-336
External Database Synchronization Utility
For synchronization tasks, the sync package provide utilities to generate raw SQL for updates, inserts, and deletes against external systems. This utilizes the squirrel SQL builder.
func getUpdateSql(schemaName string, tableName string, columnNames []string, newColumnVal []interface{}, pkColumnNames []string, pkColumnValue []interface{}) (string, []interface{}, error) {
updateSql := squirrel.Update(schemaName + "." + tableName)
for i, columnName := range columnNames {
updateSql = updateSql.Set(columnName, newColumnVal[i])
}
// ... logic for WHERE clause with PKs
}
Sources: sync/util.go:21-36
Summary
The Data Models and ORM system in Casdoor provide a robust abstraction layer for identity management. By combining XORM for general persistence, Casbin for access control modeling, and specialized initialization logic, the project ensures data integrity across multiple database platforms and complex deployment scenarios. The use of transactions in triggers and strict grammar checking for models prevents inconsistent states in the security configuration.