ayela-emmanuel/ayela-orm

This packge Is a Minimal ORM Setup for interacting with your SQL Database using PDO but abstracts the Database to a more OOP Approch

Installs: 42

Dependents: 1

Suggesters: 0

Security: 0

Stars: 3

Watchers: 1

Forks: 0

Open Issues: 0

pkg:composer/ayela-emmanuel/ayela-orm

1.0.1 2024-12-17 19:27 UTC

This package is auto-updated.

Last update: 2025-12-04 22:32:16 UTC


README

AyelaORM is a lightweight PHP Object-Relational Mapping (ORM) package designed to simplify database interactions using PHP's PDO extension. It provides an easy-to-use interface for managing database schemas and objects, dynamically handles table creation and updates, and supports relationships between models, reducing the need for manual schema management and complex SQL queries.

Table of Contents

  1. Installation
  2. Usage
  3. Advanced Querying
  4. Schema Management
  5. Data Types and Serialization
  6. Error Handling
  7. License

Installation

Install the package using Composer:

composer require ayela-emmanuel/ayela-orm

Ensure that the PDO extension is enabled for your PHP installation (MySQL is the default). Add the necessary namespace AyelaORM to your project.

Usage

Database Setup

Before using AyelaORM, you must set up the database connection:

use AyelaORM\Database;

Database::setup('localhost', 'database_name', 'username', 'password', false);
  • host: Database server host (e.g., localhost).
  • db: Database name.
  • username: Database username.
  • password: Database password.
  • frozen: If true, the database schema will not be checked or updated automatically.

Creating Models

To create a model that interacts with the database, extend the DatabaseObject class:

namespace Models;

use AyelaORM\DatabaseObject;
use AyelaORM\SQLType;
use AyelaORM\SQLIgnore;

class User extends DatabaseObject
{
    public string $db_username;
    public string $db_email;
    public int $db_age;
    public \DateTime $db_created_at;

    #[SQLIgnore]
    public string $password; // Will not be stored in the database

    public function __construct()
    {
        parent::__construct();
        $this->db_created_at = new \DateTime();
    }
}

Notes:

  • Property Naming: Properties intended for database storage should be prefixed with db_. The prefix is removed when mapping to the database column.
  • Type Handling: The class infers SQL data types from PHP property types.
  • Attributes:
    • Use #[SQLType("...")] to specify a custom SQL type for a property.
    • Use #[SQLIgnore] to exclude properties from the database schema.

Register your model on startup to ensure the schema is up to date:

Models\User::register();

Saving Data

To save a new object to the database:

$user = new Models\User();
$user->db_username = 'john_doe';
$user->db_email = 'john@example.com';
$user->db_age = 30;
$user->password = 'securepassword'; // Will not be saved to the database
$user->save();

After saving, the db_id property will be populated with the primary key value from the database.

Retrieving Data

You can retrieve records using several built-in methods.

Get All Records

$users = Models\User::list(1, 10); // Retrieve the first 10 users (page 1).

Get a Record by ID

$user = Models\User::getById(1);

Get the First Record

$user = Models\User::first();

Updating Data

Update a field of a record by ID:

Models\User::update(1, 'email', 'newemail@example.com');

Deleting Data

Delete a Single Record

Models\User::delete(1);

Delete Multiple Records

$ids = [2, 3, 4];
Models\User::deleteGroup($ids);

Advanced Querying

AyelaORM provides advanced querying capabilities without the need to write raw SQL. The findWhere and firstWhere methods allow you to retrieve records based on conditions.

Simple Conditions

Provide an associative array where keys are field names and values are the values to match.

$users = Models\User::findWhere(['username' => 'john_doe']);

Retrieve the first matching record:

$user = Models\User::firstWhere(['email' => 'john@example.com']);

Advanced Conditions

Provide an array of condition arrays, each containing a field, operator, and value.

$users = Models\User::findWhere([
    ['age', '>', 25],
    ['status', '=', 'active']
]);

Supported operators: =, >, <, >=, <=, !=, <>, LIKE.

Relationships (Joins)

AyelaORM supports relationships between models using foreign keys.

Defining Relationships

class Author extends DatabaseObject
{
    public string $db_name;
    public string $db_email;
}

class Book extends DatabaseObject
{
    public string $db_title;
    public Author $db_author; // Relationship to Author
}

Saving Data with Relationships

$author = new Models\Author();
$author->db_name = 'Jane Doe';
$author->db_email = 'jane@example.com';
$author->save();

$book = new Models\Book();
$book->db_title = 'Learning AyelaORM';
$book->db_author = $author; // Set the Author object
$book->save();

Retrieving Data with Relationships

$book = Models\Book::getById(1);
echo $book->db_title; // Outputs: Learning AyelaORM
echo $book->db_author->db_name; // Outputs: Jane Doe

One-to-Many and Many-to-Many Relationships

One-to-Many Example

In the Author class, add a method to retrieve related Book objects:

class Author extends DatabaseObject
{
    // ...

    public function getBooks(): array
    {
        return Models\Book::findWhere([['author', '=', $this->db_id]]);
    }
}

// Usage
$author = Models\Author::getById(1);
$books = $author->getBooks();

Many-to-Many Example

Create a join table model:

class Student extends DatabaseObject
{
    public string $db_name;

    public function enrollInCourse(Course $course)
    {
        $enrollment = new StudentCourse();
        $enrollment->db_student = $this;
        $enrollment->db_course = $course;
        $enrollment->save();
    }

    public function getCourses(): array
    {
        $enrollments = StudentCourse::findWhere([['student', '=', $this->db_id]]);
        return array_map(fn($enrollment) => $enrollment->db_course, $enrollments);
    }
}

class Course extends DatabaseObject
{
    public string $db_title;

    public function getStudents(): array
    {
        $enrollments = StudentCourse::findWhere([['course', '=', $this->db_id]]);
        return array_map(fn($enrollment) => $enrollment->db_student, $enrollments);
    }
}

class StudentCourse extends DatabaseObject
{
    public Student $db_student;
    public Course $db_course;
}

Schema Management

AyelaORM automatically manages database schema changes. Whenever you define or modify properties in your models, AyelaORM checks and updates the table structure accordingly.

Automatic Schema Updates

If you set frozen to false during the database setup, the schema will be checked and updated on each model instantiation. Tables will be created if they do not exist, and columns will be added or modified when changes are detected.

Database::setup('localhost', 'database_name', 'username', 'password', false);

Custom SQL Types

You can specify custom SQL types for your model properties using the #[SQLType("...")] attribute.

class Article extends DatabaseObject
{
    #[SQLType("TEXT")]
    public string $db_content;

    #[SQLType("VARCHAR(100) UNIQUE")]
    public string $db_slug;
}

Ignoring Properties

To exclude a property from the database schema, use the #[SQLIgnore] attribute.

class User extends DatabaseObject
{
    #[SQLIgnore]
    public string $password; // Will not be stored in the database
}

Data Types and Serialization

AyelaORM handles various data types, including:

  • Scalar Types: int, float, string, bool
  • DateTime: Automatically converted to and from database date-time format
  • DatabaseObject Subclasses: Stored as foreign keys (relationships)
  • Arrays and Serializable Objects: Serialized to JSON before storing and deserialized when retrieving

Example of Serializable Object

class UserProfile
{
    public string $bio;
    public array $interests;
}

class User extends DatabaseObject
{
    public string $db_username;
    public UserProfile $db_profile; // Serializable object
}

// Saving
$profile = new UserProfile();
$profile->bio = 'Developer';
$profile->interests = ['coding', 'music'];

$user = new User();
$user->db_username = 'johndoe';
$user->db_profile = $profile;
$user->save();

// Retrieving
$user = User::getById(1);
echo $user->db_profile->bio; // Outputs: Developer

Error Handling

If an error occurs during database operations, it is stored in the $last_error property of the object.

$user = new Models\User();
$user->db_username = 'john_doe';

// Intentionally cause an error (e.g., missing required field)
if (!$user->save()) {
    echo "Error: " . $user->last_error->getMessage();
}

Feel free to reach out or open an issue if you encounter any problems or have suggestions for improvements!

Note: This documentation covers the latest features and provides examples to help you get started with AyelaORM. The package is designed to simplify your database interactions and manage relationships efficiently, allowing you to focus on building your application.