GitHub

Query Builder

The QueryBuilder class provides a fluent interface for building and executing database queries with support for MySQL, PostgreSQL, and SQLite.

Basic Usage

// Initialize with database connection
$db = new DB($config);
$query = new QueryBuilder($db);

// Get all records from 'users' table
$users = $query->table('users')->all();

// Get single record with where condition
$user = $query->table('users')->where('id', 1)->first();

// Count records with condition
$count = $query->table('users')->where('active', 1)->count();

// User query helper function
query('users')->where('id', 1)->first();

Core Methods

Table Operations

table(string $table): self

Sets the table name for the query.

$query->table('users');
prefix(string $prefix): self

Sets a table prefix for the query.

$query->prefix('app_')->table('users'); // Queries 'app_users'
truncate(): bool

Truncates the current table (removes all records).

$query->table('logs')->truncate();

Select Operations

select(array|string $fields = '*'): self

Specifies columns to select.

$query->select(['id', 'name']);
$query->select('id, name, email');
from(string $table, ?string $alias = null): self

Sets the table to select from with optional alias.

$query->from('users', 'u');
as(string $alias): self

Sets an alias for the current table.

$query->table('users')->as('u');

Aggregate Functions

count(): int

Counts matching records.

$activeUsers = $query->table('users')->where('active', 1)->count();
max(string $field, ?string $name = null): self

Gets the maximum value of a column.

$maxAge = $query->table('users')->max('age')->first();
min(string $field, ?string $name = null): self

Gets the minimum value of a column.

sum(string $field, ?string $name = null): self

Calculates the sum of a column.

avg(string $field, ?string $name = null): self

Calculates the average of a column.

Result Retrieval

all(): array

Gets all matching records.

$users = $query->table('users')->all();
get(): Collection

Gets results as a Collection object.

$users = $query->table('users')->get();
first(): mixed

Gets the first matching record.

$user = $query->table('users')->where('id', 1)->first();
firstOrFail(mixed $where = null): mixed

Gets first record or throws NotFoundException.

$user = $query->table('users')->where('id', 999)->firstOrFail();
last(): mixed

Gets the last record (ordered by ID descending).

latest(): array

Gets records ordered by ID descending.

Pagination

paginate(int $limit = 10, string $keyword = 'page'): Paginator

Paginates query results.

$paginator = $query->table('posts')
    ->orderDesc('created_at')
    ->paginate(15);

foreach ($paginator as $post) {
    // Display post
}
echo $paginator->links();
👉 Check the paginator documentation

CRUD Operations

Inserting Data

// Insert single record
$query->table('users')->insert([
    'name' => 'John Doe',
    'email' => 'john@example.com'
]);

// Insert multiple records
$query->table('users')->insert([
    ['name' => 'John', 'email' => 'john@example.com'],
    ['name' => 'Jane', 'email' => 'jane@example.com']
]);

// Insert with conflict handling (PostgreSQL/SQLite)
$query->table('users')->insert(
    ['id' => 1, 'name' => 'John Updated'],
    ['conflict' => ['id'], 'update' => ['name']]
);

Updating Data

// Update single record
$query->table('users')
    ->where('id', 1)
    ->update(['name' => 'Updated Name']);

// Update multiple records
$query->table('users')
    ->where('status', 'pending')
    ->update(['status' => 'active']);

// Bulk update
$query->table('users')->bulkUpdate([
    ['id' => 1, 'name' => 'John'],
    ['id' => 2, 'name' => 'Jane']
]);

Deleting Data

// Delete single record
$query->table('users')->where('id', 1)->delete();

// Delete multiple records
$query->table('users')
    ->where('last_login', '<', '2023-01-01')
    ->delete();

Query Conditions

Basic Where Clauses

// Simple equality
$query->where('status', 'active');

// With operator
$query->where('age', '>', 18);

// Multiple conditions
$query->where([
    'status' => 'active',
    'age' => 18
]);

// Raw Conditions
$query->whereRaw('created_at > :date', ['date' => '2023-01-01']);

// OR condition
$query->orWhere('status', 'inactive');

Advanced Where Clauses

// NULL checks
$query->whereNull('deleted_at');
$query->whereNotNull('email');

// IN clauses
$query->whereIn('id', [1, 2, 3]);
$query->whereNotIn('role', ['admin', 'superadmin']);

// BETWEEN
$query->between('age', 18, 30);

// LIKE
$query->like('name', 'John%');
$query->notLike('email', '%@spam.com');

// Find in Set
$query->findInSet('tags', 'tech');

// JSON conditions
$query->findInJson('meta', 'settings.notifications', 'enabled');

// Grouped conditions
$query->grouped(function($q) {
    $q->where('status', 'active')
      ->orWhere('vip', 1);
});

Joins

// Basic join
$query->table('posts')
    ->join('users', 'users.id', '=', 'posts.user_id');

// Left join
$query->table('users')
    ->leftJoin('profiles', 'profiles.user_id', '=', 'users.id');

// Join with alias
$query->table('posts', 'p')
    ->join('users as u', 'u.id', '=', 'p.user_id');

Sorting and Grouping

// Order by
$query->orderBy('created_at', 'DESC');
$query->orderDesc('price');

// Group by
$query->groupBy(['category', 'status']);

// Having
$query->having('COUNT(orders) > 5');

Limiting Results

// Limit
$query->take(10); // Get 10 records

// Limit with offset
$query->limit(20, 10); // Skip 20, get next 10

Data Mappers

// Add data transformation
$query->table('users')
    ->addMapper(function($users) {
        return array_map(function($user) {
            $user->full_name = "{$user->first_name} {$user->last_name}";
            return $user;
        }, $users);
    })
    ->all();

Database-Specific Features

// PostgreSQL RETURNING clause
$result = $query->table('users')
    ->insert(
        ['name' => 'John'],
        ['returning' => 'id']
    );

// MySQL IGNORE
$query->table('users')
    ->insert(
        ['email' => 'existing@example.com'],
        ['ignore' => true]
    );

// SQLite COLLATE
$query->collate('nocase')
    ->table('users')
    ->where('email', 'TEST@example.com'); // Case insensitive

Full Examples

Complex Query Example

$posts = $query->table('posts')
    ->as('p')
    ->select([
        'p.id',
        'p.title',
        'p.content',
        'u.name as author',
        'c.name as category'
    ])
    ->join('users as u', 'u.id', '=', 'p.user_id')
    ->join('categories as c', 'c.id', '=', 'p.category_id')
    ->where('p.published', 1)
    ->where('p.created_at', '>', '2023-01-01')
    ->orderBy('p.created_at', 'DESC')
    ->paginate(15);

Advanced Insert Example

// PostgreSQL upsert with returning
$result = $query->table('products')
    ->insert(
        [
            ['id' => 1, 'name' => 'Laptop', 'stock' => 10],
            ['id' => 2, 'name' => 'Phone', 'stock' => 20]
        ],
        [
            'conflict' => ['id'],
            'update' => ['name', 'stock'],
            'returning' => ['id', 'name']
        ]
    );
Performance Tip: Always use select() to specify only needed columns rather than selecting all with *.
Security Note: All queries are parameterized to prevent SQL injection. Never concatenate user input directly into queries.