Khadem ORM & Schema

Complete guide to the Khadem Object-Relational Mapping system, Schema Builder, Query Builder, and relationship management for Dart applications.

SchemaBuilder

The SchemaBuilder class provides methods for creating and managing database schemas using the Blueprint class for table definitions.

create()

Creates a new table with the specified structure using a Blueprint callback.

dart

  // Creating a users table
  Khadem.db.schemaBuilder.create('users', (Blueprint table) {
    table.id();
    table.string('name');
    table.string('email');
    table.string('password');
    table.timestamps();
  });
  

Parameters:

  • tableName: The name of the table to create
  • callback: A function that defines the table structure using a Blueprint

createIfNotExists()

Creates a table only if it does not already exist.

dart

  // Creating a table if it doesn't exist
  Khadem.db.schemaBuilder.createIfNotExists('posts', (Blueprint table) {
    table.id();
    table.string('title');
    table.text('content');
    table.bigInteger('user_id');
    table.timestamps();
  });
  

drop()

Drops a specified table from the database.

dart

  // Dropping a table
  Khadem.db.schemaBuilder.drop('users');
  

dropIfExists()

Drops a table if it exists.

dart

  // Dropping a table if it exists
  Khadem.db.schemaBuilder.dropIfExists('posts');
  

QueryBuilder

The QueryBuilderInterface provides a fluent interface for building and executing SQL queries, supporting operations like select, insert, update, and delete.

select()

Specifies columns to retrieve in the query.

dart

  // Selecting specific columns
  final users = await Khadem.db.table('users').select(['id', 'name', 'email']).get();
  

Parameters:

  • columns: List of column names to select

Returns: QueryBuilderInterface for method chaining

where()

Adds a WHERE clause to the query.

dart

  // Adding a WHERE clause
  final user = await Khadem.db.table('users').where('email', '=', 'test@example.com').first();
  

Parameters:

  • column: Column name
  • operator: Comparison operator (e.g., '=', '>', '<')
  • value: Value to compare against

get()

Executes the query and returns all matching results as a list of type T.

dart

  // Fetching all users
  final users = await Khadem.db.table('users').get();
  
  // Fetching with conditions
  final activeUsers = await Khadem.db.table('users').where('status', '=', 'active').get();
  

insert()

Inserts a new record into the table.

dart

  // Inserting a new user
  final id = await Khadem.db.table('users').insert({
    'name': 'John Doe',
    'email': 'john@example.com',
    'password': 'hashed_password',
  });
  

Parameters:

  • data: Map of column names to values

paginate()

Fetches a paginated list of results.

dart

  // Paginating users
  final result = await Khadem.db.table('users').paginate(perPage: 10, page: 2);
  print('Total: ${result.total}, Page: ${result.currentPage}');
  

Parameters:

  • perPage: Number of items per page (default: 10)
  • page: Page number to fetch (default: 1)

withRelations()

Loads related models eagerly.

dart

  // Eager loading user and comments
  final post = await Khadem.db.table('posts').withRelations(['user', 'comments']).first();
  

Parameters:

  • relations: List of relation names or configurations

Relationships & Eager Loading

The framework supports eager loading of relationships through the withRelations() method in the query builder, supporting various relation types like hasOne, hasMany, belongsTo, and belongsToMany.

withRelations()

Loads specified relationships eagerly when executing queries.

dart

  // Loading relations for models using query builder
  final posts = await Khadem.db.table('posts').withRelations(['user', 'comments']).get();
  

Parameters:

  • relations: List of relation names to load

Relation Types

The framework supports different relationship types through RelationDefinition.

dart

  // Using relations in query builder
  final posts = await Khadem.db.table('posts')
      .withRelations(['user', 'comments'])
      .where('published', '=', true)
      .get();
  

Supported relation types: hasOne, hasMany, belongsTo, belongsToMany

KhademModel

The KhademModel class is the base class for all models, providing serialization, relationship management, and database operations.

Defining a Model

Extend KhademModel to create a model with fields, relations, and database interaction.

dart

  class User extends KhademModel<User> with Timestamps, HasRelationships {
    String? name;
    String? email;
    String? password;
  
    User({this.name, this.email, this.password, int? id}) {
      this.id = id;
    }
  
    @override
    List<String> get fillable => ['name', 'email', 'password', 'created_at', 'updated_at'];
  
    @override
    List<String> get hidden => ['password'];
  
    @override
    Map<String, RelationDefinition> get relations => {
      'posts': RelationDefinition<Post>(
        type: RelationType.hasMany,
        relatedTable: 'posts',
        localKey: 'id',
        foreignKey: 'user_id',
        factory: () => Post(),
      )
    };
  
    @override
    dynamic getField(String key) {
      return switch (key) {
        'id' => id,
        'name' => name,
        'email' => email,
        'password' => password,
        'created_at' => createdAt,
        'updated_at' => updatedAt,
        _ => null
      };
    }
  
    @override
    void setField(String key, dynamic value) {
      return switch (key) {
        'id' => id = value,
        'name' => name = value,
        'email' => email = value,
        'password' => password = value,
        'created_at' => createdAt = value,
        'updated_at' => updatedAt = value,
        _ => null
      };
    }
  
    @override
    User newFactory(Map<String, dynamic> data) => User()..fromJson(data);
  }
  

Key Properties:

  • fillable: Fields that can be mass-assigned
  • hidden: Fields to exclude from serialization
  • relations: Map of relationship definitions

Querying

Use the query property to build queries for the model.

dart

  // Querying users using the model's query property
  final users = await User().query.where('status', '=', 'active').orderBy('name').get();
  

Saving and Deleting

Persist or remove models using save() and delete().

dart

  // Saving a model
  final user = User(name: 'John', email: 'john@example.com');
  await user.save();
  
  // Deleting a model
  await user.delete();
  

Usage Patterns

Controller Example

dart

  class UserController {
    void getUsers(Request req, Response res) async {
      int page = int.tryParse(req.query['page'] ?? '') ?? 1;
      int perPage = int.tryParse(req.query['perPage'] ?? '') ?? 10;
      final result = await Khadem.db.table('users').paginate(perPage: perPage, page: page);
      res.sendJson({'users': result.data, 'total': result.total});
    }
  }
  

Relationship Example

dart

  // Using relationships with query builder
  final post = await Khadem.db.table('posts')
      .withRelations(['user', 'comments'])
      .where('id', '=', 1)
      .first();
  
  // Accessing loaded relations
  print(post?['user']?['name']);
  print(post?['comments']?.length);
  

On this page