nogagermainio/noga-se

Fast, fluent and immutable SQL Query Builder for PHP 8.1+ with secure parameter binding and advanced query features.

Maintainers

Package info

github.com/Noga-ng/Noga_SE

Homepage

pkg:composer/nogagermainio/noga-se

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v0.1.0 2026-07-01 16:19 UTC

This package is auto-updated.

Last update: 2026-07-01 17:09:36 UTC


README

License PHP Composer Latest Version

Status Type Architecture

MySQL PostgreSQL SQLite

Security Performance Style

Stars Forks Issues

Noga_SE is a modern, fluent, and immutable SQL QueryBuilder built in PHP 8.1+. It provides an elegant and secure API for building SELECT, INSERT, UPDATE, and DELETE queries with automatic parameter binding to prevent SQL injections.

โœจ Key Features

๐Ÿ”ง Complete CRUD Operations

  • SELECT - Complex queries with joins, subqueries, aggregations, CTEs
  • INSERT - Single and batch insertions with secure binding
  • UPDATE - Safe updates with WHERE conditions
  • DELETE - Protected deletions with conditions

๐Ÿ›ก๏ธ Advanced Security

  • Parameter Binding - Automatic binding prevents SQL injections
  • BindHashing - Cryptographically random parameter keys (:prefix_hexrand_colname)
  • Immutability - Automatic cloning prevents mutations
  • Type Safety - Strict type checking with exceptions

โš™๏ธ Powerful Features

  • Complex WHERE Clauses - AND, OR, LIKE, BETWEEN, IN, EXISTS, NOT IN
  • Joins - INNER, LEFT, RIGHT, CROSS joins with multiple tables
  • Subqueries - Nested queries via callables, Select instances, or strings
  • Aggregations - GROUP BY, HAVING, COUNT, MAX, MIN, SUM, AVG
  • Unions - UNION, UNION ALL for combining results
  • CTEs - Common Table Expressions with recursive support
  • Sorting & Pagination - ORDER BY, GROUP BY, LIMIT, OFFSET
  • Query Caching - Reuse compiled queries efficiently

๐Ÿ”— Fluent API

$query = Noga::table('users')
    ->select('id', 'name', 'email')
    ->where(['status' => 'active'])
    ->orderBy('created_at', 'DESC')
    ->limit(10);

๐ŸŽจ Design Patterns

  • Facade Pattern - Unified static API
  • Builder Pattern - Chainable query construction
  • Immutable Pattern - Safe object cloning
  • Singleton Pattern - Single instances for managers
  • Traits - Reusable functionality (conditions, aggregations)

Manual Installation

  1. Clone the repository
  2. Configure autoloading in composer.json:
{
  "autoload": {
    "psr-4": {
      "Noga\\": "src/"
    }
  }
}

๐Ÿš€ Quick Start Guide

1๏ธโƒฃ SELECT - Reading Data

Basic Query

use Noga\Noga;

$users = Noga::table('users')
    ->select('id', 'name', 'email')
    ->get();

With Conditions

$activeUsers = Noga::table('users')
    ->select('*')
    ->where(['status' => 'active', 'age >=' => 18])
    ->get();

With Joins

$userPosts = Noga::table('users')
    ->select('users.name', 'posts.title')
    ->innerJoin(Noga::joins('posts', 'p')
        ->on('users.id', '=', 'p.user_id'))
    ->get();

With Subqueries

$topUsers = Noga::table('users')
    ->select('id', 'name')
    ->whereIn('id', fn($q) => 
        $q->table('orders')
            ->select('user_id')
            ->where(['status' => 'completed'])
    )
    ->get();

With Aggregations

$stats = Noga::table('orders')
    ->select('user_id', 'COUNT(*) as total_orders')
    ->groupBy(['user_id'])
    ->having(['total_orders >' => 5])
    ->get();

With Sorting & Pagination

$topUsers = Noga::table('users')
    ->select('*')
    ->orderBy('created_at', 'DESC')
    ->limit(10)
    ->offset(20)
    ->get();

2๏ธโƒฃ INSERT - Creating Data

Executing mode :

->exec(); //interact with database
->getQuery(); //inspect Sql query string
->getValues(); //get all values
->viewState(); // show request 

Single Insertion

use Noga\Noga;

$result = Noga::insert('users')
    ->columns('name', 'email', 'status')
    ->values('John Doe', 'john@example.com', 'active')
    ->exec(); //execute mode PDO 

bulk Insertions

$result = Noga::insert('users')
    ->from(__DIR__."/../membres.json")
    ->take() // obligatory 
    ->viewState();

 json format
    // [
// {"id":"48","identifiant":"659225887","noms":"Noga","prenoms":"Germainio"},
// {"id":"48","identifiant":"659225887","noms":"Ephore","prenoms":"Miasa"},
//  ....
    // ]

Debug Insertion

$debug = Noga::insert('users')
    ->columns('name', 'email')
    ->values('Test', 'test@example.com')
    ->viewState();
    
// output
//   "sql": "INSERT INTO users( name,email )  VALUES(:in_c9f9f93a_name,:in_968abc56_email)",
//     "params": {
//         ":in_c9f9f93a_name": "Test",
//         ":in_968abc56_email": "test@example.com"
//     },
//     "driver": "mysql",
//     "table": "users",
//     "columns": [
//         "name",
//         "email"
//     ],
//     "values": [
//         "Test",
//         "test@example.com"
//     ],
//     "binding": [
//         ":in_c9f9f93a_name",
//         ":in_968abc56_email"
//     ]

3๏ธโƒฃ UPDATE - Modifying Data

execution mode :

->exec(); //interact with database
->getQuery(); //inspect Sql query string
->getValues(); //get all values
->viewState(); // show request 

Simple Update

$result = Noga::update('users')
    ->set(['status' => 'active', 'updated_at' => 'NOW()'])
    ->where(['id' => 5])
    ->exec(); //PDO request

Update with Complex Conditions

$result = Noga::update("users")
          ->set(['verified' => true])
          ->where([
        'email' => 'test@example.com',
        'status' => 'inactive'
            ])
          ->exec();

4๏ธโƒฃ DELETE - Removing Data

execution mode :

->exec(); //interact with database
->getQuery(); //inspect Sql query string
->getParams(); //get all params binding
->viewState(); // show request 

Simple Deletion

$result = Noga::delete('users')
    ->where(['id' => 1])
    ->exec();

Safe Deletion with Limits

$result = Noga::delete('users')
    ->where(['status' => 'inactive', 'last_login <' => '2023-01-01'])
    ->limit(100)
    ->exec(); //PDO

//  output with ->viewState();

//   "Query": " DELETE FROM users 
//              WHERE status = :wh_c7e10fa3_status AND last_login < :wh_1878caa8_last_login  
//              LIMIT 100 ",
//     "params": {
//         ":wh_c7e10fa3_status": "inactive",
//         ":wh_1878caa8_last_login": "2023-01-01"
//     },
//     "table": "users",
//     "driver": "mysql"

๐Ÿ“š Complete API Reference

SELECT Methods

Column Selection

->select('id', 'name', 'email')           // Specific columns
->select('*')                             // All columns
->distinct(true)                          // Remove duplicates
->selectCase(fn($case) =>$case->when("id","12")->else("25")->as("c"), 'status')  // CASE WHEN expressions
//or
->selectCase(Noga::c("id","12")->else("25")->as("c"), 'status')  

WHERE Clauses

->where(['id' => 1, 'status' => 'active'])              // AND condition
->whereOr(['status' => 'pending', 'status' => 'draft']) // OR condition
->whereLike(['name' => 'john'])                         // LIKE search
->whereIn('id', [1, 2, 3])                              // IN clause
->whereNotIn('id', [10, 20])                            // NOT IN clause
->whereBetween(['age' => [18, 65]])                     // BETWEEN range
->whereColumn('created_at', '>', 'updated_at')          // Column comparison
->isNull('deleted_at')                                  // IS NULL
->isNotnull('verified_at')                              // IS NOT NULL
->whereExists(fn($q) => ...)                            // EXISTS subquery
->whereNotExists(fn($q) => ...)                         // NOT EXISTS

Joins

->innerJoin(Noga::j('posts', 'p')
    ->on('users.id', '=', 'p.user_id'))

->leftJoin(Noga::j('comments', 'c')
    ->on('posts.id', '=', 'c.post_id'))

->rightJoin(Noga::j('categories', 'cat')
    ->on('posts.category_id', '=', 'cat.id'))

->crossJoin(Noga::j('departments', 'd'))

Grouping & Aggregation

->groupBy(['status', 'created_at'])
->having(['count >' => 5])

Sorting & Pagination

->orderBy('created_at', 'DESC')  // ASC or DESC
->limit(10)                       // Limit results
->offset(20)                      // Skip results

Unions

//union simple 
->union(Noga::u()->table('admins')->select('id', 'name'))
->unionAll(Noga::u()->table('moderators')->select('id', 'name'))

//union with table dynamique
->unionAll(Noga::u()->from(['admin','moderators'])->select('id','name')) 

// union with a condition multiple
->unionAll(Noga::u()->add([
    Noga::table("users")
    ->select("id","noms")
    ->where(["id"=>12])
    ])) 

CTEs (Common Table Expressions)

->with('recent_users', 
    fn($q) => $q->table('users')
        ->where(['created_at >' => 'NOW()'])
)

->with('category_tree', 
    fn($q) => $q->table('categories')
        ->select('id', 'name', 'parent_id')
        ->where(['parent_id' => null]),
    true  // Recursive
)

Execution Methods

->get()                    // All results as objects
->getOne()                 // Single row
->getStream()              // Generator for large datasets
->getQuery()                 // Compiled SQL string
->getParams()              // Bound parameters array
->viewState()               // Complete request info

๐Ÿ—๏ธ Project Architecture

src/
โ”œโ”€โ”€ Noga.php                             # Main Facade
โ”œโ”€โ”€ QueryBuilder/
โ”‚   โ”œโ”€โ”€ builder.php                     # Clause construction
โ”‚   โ”œโ”€โ”€ select/                         # SELECT implementation
โ”‚   โ””โ”€โ”€ crud/                           # INSERT, UPDATE, DELETE
โ”œโ”€โ”€ Core/
โ”‚   โ”œโ”€โ”€ BindHashing.php                 # Secure parameter hashing
โ”‚   โ”œโ”€โ”€ CacheManager.php                # Query caching
โ”‚   โ”œโ”€โ”€ Sqlast.php                      # SQL parsing & AST
โ”‚   โ”œโ”€โ”€ NgManager.php                   # Configuration management
โ”‚   โ””โ”€โ”€ DateManager.php                 # Date formatting (FR/EN)
โ”œโ”€โ”€ Db/
โ”‚   โ”œโ”€โ”€ DB.php                          # Database abstraction
โ”‚   โ”œโ”€โ”€ mysql.php                       # MySQL driver
โ”‚   โ”œโ”€โ”€ postgres.php                    # PostgreSQL driver
โ”‚   โ””โ”€โ”€ sqlite.php                      # SQLite driver
โ”œโ”€โ”€ Traits/
โ”‚   โ”œโ”€โ”€ BuidlerAttr.php                 # Builder attributes
โ”‚   โ”œโ”€โ”€ aggregate.php                   # Aggregation functions
โ”‚   โ”œโ”€โ”€ condition.php                   # Condition building
โ”‚   โ””โ”€โ”€ dbTrait.php                     # Database connection
โ”œโ”€โ”€ helpers/
โ”‚   โ””โ”€โ”€ helpers.php                     # Utility functions
โ”œโ”€โ”€ CLI/
โ”‚   โ”œโ”€โ”€ kernel.php                      # Command dispatcher
โ”‚   โ””โ”€โ”€ commands/                       # Custom commands
โ”œโ”€โ”€ cache/                              # Query cache storage
โ”œโ”€โ”€ exceptions/                         # Custom exceptions
โ””โ”€โ”€ mapping/                            # Data mapping

๐Ÿ”’ Security in Depth

Parameter Binding (SQL Injection Prevention)

// โŒ UNSAFE - Vulnerable to SQL injection
$query = "SELECT * FROM users WHERE id = $id";

// โœ… SAFE - Parameters are bound
$query = Noga::table('users')
    ->where(['id' => $id])  // Automatically bound
    ->get();

BindHashing Mechanism

Parameter Key Generation:
Input: ['id' => 5, 'status' => 'active']

โ†“ BindHashing::hash()

Output: 
  :wh_a1b2c3d4_id => 5
  :wh_e5f6g7h8_status => "active"

Each key is:
- Prefixed (:wh_ for WHERE)
- Random hex (a1b2c3d4)
- Column name
- Cryptographically secure
- Impossible to predict or inject

Immutability for Safety

$base = Noga::table('users');
$active = $base->where(['status' => 'active']);
$admins = $base->where(['role' => 'admin']);

// $base, $active, $admins are 3 different objects
// No side effects or shared state

๐Ÿงช Testing

Run Tests

# Unix/Linux/Mac
./noga test

# Windows
noga.bat test

Test Files

  • test/NogaTest.php - PHPUnit test suite
  • test/test.php - Basic examples
  • test/users.php - User table examples

Test Configuration

<!-- phpunit.xml -->
<phpunit bootstrap="vendor/autoload.php">
    <testsuites>
        <testsuite name="Builder SQL Suite">
            <directory>./test</directory>
        </testsuite>
    </testsuites>
</phpunit>

๐Ÿ’ก Advanced Examples

Complex Multi-Level Query

$results = Noga::table('orders')
    ->select(
        'orders.id',
        'orders.total',
        'customers.name',
        'COUNT(items.id) as item_count'
    )
    ->innerJoin(Noga::joins('customers', 'c')
        ->on('orders.customer_id', '=', 'c.id'))
    ->innerJoin(Noga::joins('order_items', 'items')
        ->on('orders.id', '=', 'items.order_id'))
    ->where([
        'orders.status' => 'completed',
        'orders.created_at >=' => '2024-01-01'
    ])
    ->groupBy(['orders.id', 'customers.name'])
    ->having(['item_count >' => 3])
    ->orderBy('orders.total', 'DESC')
    ->limit(20)
    ->get();

Recursive CTE

$hierarchy = Noga::table('categories')
    ->with('category_tree', 
        fn($q) => $q->table('categories')
            ->select('id', 'name', 'parent_id')
            ->where(['parent_id' => null]),
        true  // Recursive
    )
    ->select('*')
    ->get();

    //or
    $hierarchy = Noga::table('categories')
    ->with('category_tree', 
        Noga::table('categories')
            ->select('id', 'name', 'parent_id')
            ->where(['parent_id' => null]),
        true  // Recursive
    )
    ->select('*')
    ->get();

Query Caching

// Register query
Noga::table('users')
    ->select('id', 'name')
    ->where(['status' => 'active'])
    ->add_query('get_active_users');

// Reuse from cache
$users = Noga::use_query('get_active_users')->get();

// Clear cache
Noga::removeCache('get_active_users');
Noga::removeAllCache();

EXPLAIN Query Analysis

$analysis = Noga::explain(
    Noga::table('users')
        ->select('*')
        ->where(['id' => 1]),
    'FORMAT=JSON'
);

๐Ÿ”ง Configuration

Database Configuration

Configure via NgManager or environment file:

// Initialize configuration
$config = NgManager::getInstance('path/to/ngconfig.ng');

// Access parameters
$host = ng('db_host');
$port = ng('db_port', 3306);

Cache Configuration

CacheManager::key("my_query")
    ->dir("queries")
    ->delay(3600)  // 1 hour
    ->data($result)
    ->put();

๐ŸŽฏ Use Cases

โœ… Modern Web Applications - Build safe, fluent queries
โœ… API Development - Complex data retrieval with filters
โœ… Data Analysis - Aggregations, CTEs, subqueries
โœ… Reporting Systems - Multi-table joins and summaries
โœ… Admin Dashboards - Dynamic filtering and sorting
โœ… Microservices - Database abstraction layer

๐Ÿค Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the project
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit changes (git commit -m 'Add some AmazingFeature')
  4. Push to branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Development Setup

# Clone repository
git clone https://github.com/nogagermainio/Noga_SE.git
cd Noga_SE

# Install dependencies
composer install

# Run tests
./noga test

# Check code
./noga lint

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

MIT License

Copyright (c) 2026 nogagermainio

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions above.

๐Ÿ‘จโ€๐Ÿ’ป Author

nogagermainio

๐Ÿ”— Related Projects

๐Ÿ†˜ Support & Issues

Found a bug? Want a feature? Please open an issue with:

  • โœ… Clear problem description
  • โœ… Minimal code reproduction
  • โœ… Expected vs actual behavior
  • โœ… PHP version and OS

Common Issues

Q: How do I prevent SQL injection?
A: All parameters are automatically bound via BindHashing. Never concatenate user input!

Q: Can I cache queries?
A: Yes! Use ->add_query('name') and Noga::use_query('name')

Q: Is it compatible with my database?
A: Noga_SE supports MySQL, PostgreSQL, SQLite, and is easily extended for others.

Q: How do I contribute?
A: Fork the repo, create a feature branch, and submit a pull request.

๐Ÿ“Š Roadmap

โœ… Completed

  • SELECT with advanced clauses
  • INSERT with secure binding
  • UPDATE with conditions
  • DELETE with protection
  • Joins (INNER, LEFT, RIGHT, CROSS)
  • Subqueries & nesting
  • Unions & intersections
  • Recursive CTEs
  • Immutability & cloning
  • Query caching

๐Ÿ”„ In Progress

  • Enhanced error reporting
  • Performance profiling
  • Query optimization hints
  • Additional database drivers

๐Ÿ“‹ Planned

  • Trigger & stored procedure support
  • Database schema builders
  • Migration system
  • Query logging middleware
  • Batch optimization
  • Full-text search support

๐Ÿ“ˆ Performance Tips

  1. Use Pagination - Limit large result sets

    ->limit(20)->offset($page * 20)
  2. Cache Frequently Used Queries - Reuse compiled queries

    ->add_query('active_users')
  3. Use Indexes - Create database indexes on WHERE columns

    CREATE INDEX idx_status ON users(status);
  4. Batch Operations - Insert multiple rows at once

    ->values(...)->values(...)->values(...)
  5. Select Only Needed Columns - Avoid SELECT *

    ->select('id', 'name', 'email')  // Not SELECT *

๐Ÿ“ž Community & Discussions

๐ŸŒŸ Show Your Support

If you find Noga_SE helpful, please consider:

  • โญ Star the repository
  • ๐Ÿด Fork and contribute
  • ๐Ÿ“ข Share with your network
  • ๐Ÿ’ฌ Leave feedback

Made with โค๏ธ by nogagermainio

Last updated: 2026-07-01
Version: 1.0.0