PHP code example of progrmanial / simple-mysqli-fork

1. Go to this page and download the library: Download progrmanial/simple-mysqli-fork library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

progrmanial / simple-mysqli-fork example snippets


// All the enterprise data types you need
$table->increments('id')                    // Auto-increment primary key
      ->uuid('external_id')                 // UUID storage (36 chars)
      ->ulid('session_id')                  // ULID storage (26 chars)
      ->ipAddress('client_ip')              // IPv4/IPv6 (45 chars)
      ->macAddress('device_mac')            // MAC address (17 chars)
      ->json('preferences')                 // JSON data storage
      ->morphs('taggable');                 // Polymorphic relationships

// Precise numeric handling
$table->float('rating', 3, 2)              // Single precision: 0.00-9.99
      ->double('coordinates', 10, 8)        // Double precision coordinates
      ->decimal('price', 10, 2)             // Exact monetary values
      ->tinyInteger('priority')             // -128 to 127
      ->smallInteger('count')               // -32,768 to 32,767  
      ->mediumInteger('views')              // -8,388,608 to 8,388,607
      ->bigInteger('total_bytes');          // Large integers

// Comprehensive temporal and binary support
$table->date('birth_date')                 // Date only (no time)
      ->time('meeting_time', 3)            // Time with microsecond precision
      ->year('copyright_year')             // Year storage (1901-2155)
      ->binary('file_data')                // Binary data storage
      ->char('country_code', 2);           // Fixed-length strings

// String types with different purposes
$table->string('email', 150)          // Email addresses
      ->string('password', 255)       // Encrypted passwords
      ->char('currency', 3)           // Currency codes (USD, EUR)
      ->text('bio')                   // User biography
      ->mediumText('post_content')    // Blog posts
      ->longText('system_logs');      // System logs

// All integer types support unsigned() modifier
$table->tinyInteger('age')->unsigned()              // 0 to 255
      ->smallInteger('port')->unsigned()            // 0 to 65535
      ->mediumInteger('population')->unsigned()     // 0 to 16M
      ->integer('user_id')->unsigned()              // 0 to 4B
      ->bigInteger('bytes_transferred')->unsigned(); // 0 to 18E18

// Auto-incrementing primary keys
$table->increments('id')                // UNSIGNED INT AUTO_INCREMENT
      ->bigIncrements('id')             // UNSIGNED BIGINT AUTO_INCREMENT
      ->tinyIncrements('id')            // UNSIGNED TINYINT AUTO_INCREMENT
      ->smallIncrements('id')           // UNSIGNED SMALLINT AUTO_INCREMENT
      ->mediumIncrements('id');         // UNSIGNED MEDIUMINT AUTO_INCREMENT

// Common timestamp patterns
$table->timestamps()                    // created_at, updated_at
      ->timestampsTz()                  // With timezone
      ->softDeletes()                   // deleted_at
      ->softDeletesTz()                 // deleted_at with timezone
      ->rememberToken();                // Laravel-style remember token

// Time with automatic values
$table->timestamp('created_at')->useCurrent()              // DEFAULT CURRENT_TIMESTAMP
      ->timestamp('updated_at')->useCurrentOnUpdate()      // ON UPDATE CURRENT_TIMESTAMP
      ->datetime('processed_at', 6)->nullable()             // Microsecond precision
      ->time('duration', 3);                                // Millisecond precision

// Binary data examples
$table->binary('uuid_binary', 16)      // UUID as binary
      ->varbinary('encrypted_data', 500) // Encrypted content
      ->blob('profile_image')           // Profile pictures
      ->mediumBlob('document')          // PDF files
      ->longBlob('video_file');         // Video content

// Network-related data types
$table->ipAddress('client_ip')          // IPv4/IPv6 (45 chars)
      ->macAddress('device_mac')        // MAC address (17 chars)
      ->url('website', 500)             // URL storage
      ->email('contact_email');         // Email addresses

// Spatial data types
$table->point('location')               // POINT coordinates
      ->lineString('route')             // LINESTRING paths
      ->polygon('area')                 // POLYGON regions
      ->multiPoint('locations')         // Multiple points
      ->multiLineString('routes')       // Multiple paths
      ->multiPolygon('areas')           // Multiple regions
      ->geometry('shape')               // Generic geometry
      ->geometryCollection('shapes');   // Collection of geometries

// Polymorphic relationship examples
$table->morphs('commentable');          // commentable_id, commentable_type
// Equivalent to:
// $table->unsignedInteger('commentable_id');
// $table->string('commentable_type');
// $table->index(['commentable_id', 'commentable_type']);

$schema->createTable('products', function($table) {
    $table->increments('id');
    $table->string('sku', 50)->unique();
    $table->string('name', 200);
    $table->text('description')->nullable();
    $table->decimal('price', 10, 2)->unsigned();
    $table->decimal('compare_price', 10, 2)->unsigned()->nullable();
    $table->smallInteger('stock_quantity')->unsigned()->default(0);
    $table->float('weight', 8, 2)->nullable();
    $table->json('attributes')->nullable();             // Color, size, etc.
    $table->json('images')->nullable();                 // Image URLs
    $table->boolean('featured')->default(false);
    $table->boolean('active')->default(true);
    $table->enum('status', ['draft', 'published', 'archived'])->default('draft');
    $table->timestamps();
});

$schema->createTable('user_profiles', function($table) {
    $table->increments('id');
    $table->unsignedInteger('user_id')->unique();
    $table->string('first_name', 50);
    $table->string('last_name', 50);
    $table->date('birth_date')->nullable();
    $table->enum('gender', ['male', 'female', 'other'])->nullable();
    $table->string('phone', 20)->nullable();
    $table->text('bio')->nullable();
    $table->json('preferences')->nullable();
    $table->json('social_links')->nullable();
    $table->blob('avatar')->nullable();
    $table->ipAddress('last_login_ip')->nullable();
    $table->timestamp('last_login_at')->nullable();
    $table->timestamps();
    
    $table->foreignKey('user_id', 'users', 'id', 'CASCADE');
});

$schema->createTable('analytics_events', function($table) {
    $table->bigIncrements('id');
    $table->uuid('session_id');
    $table->string('event_type', 50);
    $table->string('event_name', 100);
    $table->json('properties')->nullable();
    $table->json('context')->nullable();
    $table->ipAddress('ip_address');
    $table->string('user_agent', 500);
    $table->string('referrer', 500)->nullable();
    $table->point('location')->nullable();              // Geographic location
    $table->timestamp('created_at', 6);                 // Microsecond precision
    
    // Optimized for time-series queries
    $table->index(['event_type', 'created_at']);
    $table->index(['session_id', 'created_at']);
});

$table->string('product_name', 200)
      ->comment('SEO-optimized product name')
      ->columnCharset('utf8mb4')
      ->columnCollation('utf8mb4_unicode_ci')
      ->nullable(false)
      ->default('')
      ->after('sku')
      ->invisible(false);

$table->decimal('account_balance', 15, 2)
      ->unsigned()                        // Only positive values
      ->default(0.00)                     // Default balance
      ->comment('Account balance in USD') // Documentation
      ->nullable(false)                   // Required field
      ->after('account_id');              // Position after account_id

// Created timestamp - set once
$table->timestamp('created_at', 6)
      ->useCurrent()                      // DEFAULT CURRENT_TIMESTAMP(6)
      ->comment('Record creation time')
      ->nullable(false);

// Updated timestamp - auto-update
$table->timestamp('updated_at', 6)
      ->useCurrent()                      // DEFAULT CURRENT_TIMESTAMP(6)
      ->useCurrentOnUpdate()              // ON UPDATE CURRENT_TIMESTAMP(6)
      ->comment('Last modification time')
      ->nullable(false);

// Multi-language content
$table->text('content')
      ->columnCharset('utf8mb4')
      ->columnCollation('utf8mb4_unicode_ci')
      ->comment('Multi-language content')
      ->nullable(true);

// Case-insensitive search
$table->string('search_term', 100)
      ->columnCharset('utf8mb4')
      ->columnCollation('utf8mb4_general_ci')   // Case-insensitive
      ->comment('Search term for indexing');

// Internal tracking columns
$table->uuid('internal_tracking_id')
      ->comment('Internal system tracking ID')
      ->invisible()                       // Hidden from SELECT *
      ->default('UUID()');

// Audit columns
$table->json('audit_metadata')
      ->comment('Internal audit information')
      ->invisible()                       // Hidden from application
      ->nullable();

// ✅ Valid combinations
$table->string('name', 100)
      ->nullable()
      ->default('')
      ->comment('User name')
      ->after('id');

$table->integer('count')
      ->unsigned()
      ->default(0)
      ->comment('Item count');

$table->timestamp('created_at')
      ->useCurrent()
      ->comment('Creation timestamp');

// ❌ Invalid: unsigned() only works with numeric types
$table->string('name')->unsigned();     // Error!

// ❌ Invalid: useCurrent() only works with timestamp types
$table->string('name')->useCurrent();   // Error!

// ❌ Invalid: columnCharset() only works with string types
$table->integer('count')->columnCharset('utf8mb4');  // Error!

$schema->createTable('users', function($table) {
    $table->increments('id');
    
    // Name fields with proper charset
    $table->string('first_name', 50)
          ->comment('User first name')
          ->columnCharset('utf8mb4')
          ->columnCollation('utf8mb4_unicode_ci');
    
    $table->string('last_name', 50)
          ->comment('User last name')
          ->columnCharset('utf8mb4')
          ->columnCollation('utf8mb4_unicode_ci');
    
    // Email with case-insensitive collation
    $table->string('email', 150)
          ->unique()
          ->comment('User email address')
          ->columnCharset('utf8mb4')
          ->columnCollation('utf8mb4_general_ci');
    
    // Secure password field
    $table->string('password', 255)
          ->comment('Encrypted password hash');
    
    // Numeric fields with constraints
    $table->tinyInteger('age')
          ->unsigned()
          ->nullable()
          ->comment('User age in years');
    
    $table->decimal('account_balance', 10, 2)
          ->unsigned()
          ->default(0.00)
          ->comment('Account balance in USD');
    
    // Timestamp fields with automatic values
    $table->timestamp('created_at')
          ->useCurrent()
          ->comment('Account creation time');
    
    $table->timestamp('updated_at')
          ->useCurrent()
          ->useCurrentOnUpdate()
          ->comment('Last profile update');
    
    $table->timestamp('last_login_at')
          ->nullable()
          ->comment('Last login timestamp');
    
    // Audit columns (invisible in MySQL 8.0+)
    $table->json('audit_trail')
          ->invisible()
          ->nullable()
          ->comment('Internal audit information');
});

$schema->createTable('products', function($table) {
    $table->increments('id');
    
    // Product identification
    $table->string('sku', 50)
          ->unique()
          ->comment('Stock Keeping Unit')
          ->columnCharset('ascii')
          ->columnCollation('ascii_general_ci');
    
    // Multi-language product name
    $table->string('name', 200)
          ->comment('Product name (multi-language)')
          ->columnCharset('utf8mb4')
          ->columnCollation('utf8mb4_unicode_ci');
    
    // Pricing with proper precision
    $table->decimal('price', 10, 2)
          ->unsigned()
          ->comment('Product price in USD');
    
    $table->decimal('compare_price', 10, 2)
          ->unsigned()
          ->nullable()
          ->comment('Compare at price for discounts');
    
    // Inventory tracking
    $table->smallInteger('stock_quantity')
          ->unsigned()
          ->default(0)
          ->comment('Available stock quantity');
    
    // Product attributes
    $table->json('attributes')
          ->nullable()
          ->comment('Product attributes (color, size, etc.)');
    
    // SEO and categorization
    $table->string('slug', 200)
          ->unique()
          ->comment('URL-friendly product identifier')
          ->columnCharset('ascii')
          ->columnCollation('ascii_general_ci');
    
    // Status and visibility
    $table->boolean('active')
          ->default(true)
          ->comment('Product active status');
    
    $table->boolean('featured')
          ->default(false)
          ->comment('Featured product flag');
    
    // Timestamps
    $table->timestamp('created_at')
          ->useCurrent()
          ->comment('Product creation time');
    
    $table->timestamp('updated_at')
          ->useCurrent()
          ->useCurrentOnUpdate()
          ->comment('Last modification time');
    
    // Internal tracking (invisible)
    $table->uuid('internal_id')
          ->invisible()
          ->comment('Internal tracking UUID');
});

// Enterprise-grade column customization
$table->string('title', 200)
      ->comment('SEO-optimized page title')     // Self-documenting schemas
      ->columnCharset('utf8mb4')               // Custom character sets
      ->columnCollation('utf8mb4_unicode_ci') // Specific collations
      ->nullable()                             // Allow NULL values
      ->default('Untitled')                    // Default values
      ->after('slug')                          // Position after column
      ->invisible();                           // Hidden from SELECT *

// Numeric modifiers
$table->decimal('balance', 15, 2)
      ->unsigned()                             // Only positive values
      ->default(0.00)
      ->comment('Account balance in USD');

// Timestamp helpers
$table->timestamp('created_at')->useCurrent()          // DEFAULT CURRENT_TIMESTAMP
      ->timestamp('updated_at')->useCurrentOnUpdate()  // ON UPDATE CURRENT_TIMESTAMP
      ->timestamp('deleted_at')->nullable();            // Soft deletes

// Migration: "create_users_table" 
// ✨ Auto-generates complete user table with modern features
php artisan migration:create create_users_table

// Migration: "add_email_to_customers"
// ✨ Auto-detects VARCHAR(255) for email + unique constraint
php artisan migration:create add_email_to_customers

// Migration: "add_is_active_to_posts" 
// ✨ Auto-detects BOOLEAN type for is_* fields
php artisan migration:create add_is_active_to_posts

// Intelligently generated based on migration name
public function up(): void
{
    $this->createTable('users', function($table) {
        $table->increments('id');
        $table->string('name')->comment('Full name');
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->date('birth_date')->nullable();
        $table->enum('status', ['active', 'inactive', 'pending'])->default('active');
        $table->json('preferences')->nullable();
        $table->ipAddress('last_login_ip')->nullable();
        $table->rememberToken();                // Laravel-style auth token
        $table->timestamps();                   // created_at, updated_at
        $table->softDeletes();                  // deleted_at
    });
}

// All identifiers properly escaped
$table->string('user-name')        // Becomes `user-name` in SQL
      ->comment("User's full name"); // Becomes COMMENT 'User\'s full name'

// All values parameterized  
$table->enum('status', ["'admin'", '"user"'])  // Properly escaped enum values
      ->default("'pending'");                   // Safe default handling

// 65+ MySQL reserved words detected
$table->string('select');     // ❌ Error: 'select' is a MySQL reserved word

// Length validation with helpful messages
$table->string('title', 70000); // ❌ Error: VARCHAR length must be between 1 and 65535, got 70000

// Type compatibility checking
$table->json('data')->unsigned(); // ❌ Error: unsigned() can only be used with numeric columns


SimpleMDB\DatabaseFactory;
use SimpleMDB\SchemaBuilder;

// Test connection
try {
    $db = DatabaseFactory::create('pdo', 'localhost', 'root', 'password', 'test');
    echo "✅ SimpleMDB installed successfully!\n";
    echo "Version: " . SimpleMDB\SimpleMySQLi::VERSION . "\n";
} catch (Exception $e) {
    echo "❌ Installation issue: " . $e->getMessage() . "\n";
}

use SimpleMDB\DatabaseFactory;

// Basic PDO connection
$config = [
    'driver' => 'pdo',
    'host' => 'localhost',
    'port' => 3306,
    'database' => 'myapp',
    'username' => 'root',
    'password' => 'password',
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci'
];

$db = DatabaseFactory::create($config);

// Enterprise configuration with all options
$config = [
    'driver' => 'pdo',
    'host' => 'localhost',
    'port' => 3306,
    'database' => 'myapp',
    'username' => 'root',
    'password' => 'password',
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    
    // SSL Configuration
    'ssl' => [
        'key' => '/path/to/client-key.pem',
        'cert' => '/path/to/client-cert.pem',
        'ca' => '/path/to/ca-cert.pem',
        'capath' => '/path/to/ca-certs-dir',
        'cipher' => 'DHE-RSA-AES256-SHA'
    ],
    
    // Connection Options
    'options' => [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false,
        PDO::MYSQL_ATTR_FOUND_ROWS => true,
        PDO::MYSQL_ATTR_INIT_COMMAND => "SET sql_mode='STRICT_TRANS_TABLES'"
    ],
    
    // Connection Pool Settings
    'pool' => [
        'min_connections' => 5,
        'max_connections' => 20,
        'connection_timeout' => 30,
        'idle_timeout' => 600,
        'retry_attempts' => 3
    ],
    
    // Caching Configuration
    'cache' => [
        'driver' => 'redis',
        'host' => 'localhost',
        'port' => 6379,
        'database' => 0,
        'prefix' => 'simplemdb:',
        'ttl' => 3600
    ],
    
    // Debug and Profiling
    'debug' => [
        'enabled' => true,
        'log_queries' => true,
        'slow_query_threshold' => 1000, // ms
        'log_file' => '/var/log/simplemdb.log'
    ]
];

$db = DatabaseFactory::create($config);

// Using environment variables
$config = [
    'driver' => getenv('DB_DRIVER') ?: 'pdo',
    'host' => getenv('DB_HOST') ?: 'localhost',
    'port' => (int)getenv('DB_PORT') ?: 3306,
    'database' => getenv('DB_DATABASE'),
    'username' => getenv('DB_USERNAME'),
    'password' => getenv('DB_PASSWORD'),
    'charset' => getenv('DB_CHARSET') ?: 'utf8mb4',
    'collation' => getenv('DB_COLLATION') ?: 'utf8mb4_unicode_ci',
];

// .env file example
/*
DB_DRIVER=pdo
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=secret
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
*/

// Configure multiple databases
$databases = [
    'primary' => [
        'driver' => 'pdo',
        'host' => 'primary-db.example.com',
        'database' => 'app_primary',
        'username' => 'app_user',
        'password' => 'primary_password'
    ],
    'analytics' => [
        'driver' => 'pdo',
        'host' => 'analytics-db.example.com',
        'database' => 'app_analytics',
        'username' => 'analytics_user',
        'password' => 'analytics_password'
    ],
    'cache' => [
        'driver' => 'pdo',
        'host' => 'cache-db.example.com',
        'database' => 'app_cache',
        'username' => 'cache_user',
        'password' => 'cache_password'
    ]
];

// Create connections
$primaryDb = DatabaseFactory::create($databases['primary']);
$analyticsDb = DatabaseFactory::create($databases['analytics']);
$cacheDb = DatabaseFactory::create($databases['cache']);


SimpleMDB\DatabaseFactory;
use SimpleMDB\SchemaBuilder;
use SimpleMDB\SimpleQuery;

// Create database connection
$db = DatabaseFactory::create('pdo', 'localhost', 'root', 'password', 'myapp');

// Test connection
if ($db->ping()) {
    echo "Connected successfully!\n";
} else {
    echo "Connection failed!\n";
}

// Initialize schema builder
$schema = new SchemaBuilder($db);

// Create a users table with modern features
$schema->increments('id')
       ->string('name', 100)->comment('User full name')
       ->string('email', 150)->unique()
       ->string('password', 255)
       ->boolean('is_active')->default(true)
       ->json('preferences')->nullable()
       ->ipAddress('last_login_ip')->nullable()
       ->timestamps() // created_at, updated_at
       ->softDeletes() // deleted_at
       ->createTable('users');

echo "✅ Users table created successfully!\n";

// Insert a single user
$userId = SimpleQuery::create()
    ->insert('users')
    ->values([
        'name' => 'John Doe',
        'email' => '[email protected]',
        'password' => password_hash('secret123', PASSWORD_DEFAULT),
        'is_active' => true,
        'preferences' => json_encode(['theme' => 'dark', 'notifications' => true])
    ])
    ->execute($db);

echo "✅ User created with ID: $userId\n";

// Find active users
$users = SimpleQuery::create()
    ->select(['id', 'name', 'email', 'created_at'])
    ->from('users')
    ->where('is_active = ?', [true])
    ->where('deleted_at IS NULL')
    ->orderBy('created_at DESC')
    ->limit(10)
    ->execute($db);

echo "Found " . count($users) . " active users\n";
foreach ($users as $user) {
    echo "- {$user['name']} ({$user['email']})\n";
}

// Update user preferences
$affected = SimpleQuery::create()
    ->update('users')
    ->set([
        'preferences' => json_encode(['theme' => 'light', 'notifications' => false]),
        'updated_at' => date('Y-m-d H:i:s')
    ])
    ->where('id = ?', [$userId])
    ->execute($db);

echo "✅ Updated $affected user(s)\n";

use SimpleMDB\Migrations\MigrationManager;

// Initialize migration manager
$migrations = new MigrationManager($db);

// Create a migration (generates intelligent template)
$migrationFile = $migrations->create('create_blog_posts_table');
echo "✅ Migration created: $migrationFile\n";

// Run all pending migrations
$migrations->migrate();
echo "✅ All migrations completed!\n";

// Check migration status
foreach ($migrations->status() as $migration) {
    echo "📄 {$migration['name']}: {$migration['status']}\n";
}

use SimpleMDB\SchemaBuilder;

// Create schema builder instance
$schema = new SchemaBuilder($db);

// Check if table exists
if ($schema->hasTable('users')) {
    echo "Users table exists\n";
}

// Get table column information
$columns = $schema->getColumns('users');
foreach ($columns as $column) {
    echo "Column: {$column['name']} ({$column['type']})\n";
}

// Drop table if exists
$schema->dropIfExists('old_table');

// Method 1: Fluent interface (recommended)
$schema->increments('id')
       ->string('name', 100)->comment('User full name')
       ->string('email', 150)->unique()
       ->timestamps()
       ->createTable('users');

// Method 2: Callback syntax
$schema->createTable('posts', function($table) {
    $table->increments('id');
    $table->string('title', 200);
    $table->text('content');
    $table->unsignedInteger('user_id');
    $table->timestamps();
    
    // Add foreign key constraint
    $table->foreignKey('user_id', 'users', 'id');
});

// Method 3: Advanced table creation
$schema->createTable('products', function($table) {
    $table->increments('id');
    $table->string('sku', 50)->unique();
    $table->string('name', 200);
    $table->text('description')->nullable();
    $table->decimal('price', 10, 2)->unsigned();
    $table->json('attributes')->nullable();
    $table->enum('status', ['active', 'inactive', 'discontinued'])->default('active');
    $table->timestamps();
    
    // Indexes
    $table->index(['name'], 'product_name_idx');
    $table->index(['status', 'price'], 'status_price_idx');
    $table->unique(['sku'], 'unique_sku');
});

// Add columns to existing table
$schema->addColumn('users', 'phone', 'string', 20, [
    'nullable' => true,
    'comment' => 'User phone number'
]);

// Modify existing column
$schema->modifyColumn('users', 'phone', 'string', 25, [
    'nullable' => false,
    'default' => ''
]);

// Drop column
$schema->dropColumn('users', 'phone');

// Rename column
$schema->renameColumn('users', 'phone', 'mobile_phone');

// Add index
$schema->addIndex('users', ['email'], 'email_idx');

// Drop index
$schema->dropIndex('users', 'email_idx');

// Rename table
$schema->renameTable('old_users', 'users');

// Truncate table (remove all data)
$schema->truncateTable('temporary_data');

// Drop table
$schema->dropTable('unused_table');

// Drop table if exists
$schema->dropIfExists('maybe_exists');

// Get table schema
$tableSchema = $schema->getTableSchema('users');
print_r($tableSchema);

$schema->createTable('orders', function($table) {
    $table->increments('id');
    $table->unsignedInteger('user_id');
    $table->decimal('total', 10, 2);
    $table->timestamps();
    
    // Foreign key constraint
    $table->foreignKey('user_id', 'users', 'id', 'CASCADE', 'CASCADE');
    
    // Composite foreign key
    $table->foreignKey(['user_id', 'status'], 'user_status', ['user_id', 'status']);
    
    // Check constraint
    $table->checkConstraint('total > 0', 'positive_total');
});

// Add foreign key to existing table
$schema->addForeignKey('orders', 'user_id', 'users', 'id');

// Drop foreign key
$schema->dropForeignKey('orders', 'orders_user_id_foreign');

$schema->createTable('search_index', function($table) {
    $table->increments('id');
    $table->string('title', 200);
    $table->text('content');
    $table->string('category', 50);
    $table->timestamps();
    
    // Regular index
    $table->index(['category'], 'category_idx');
    
    // Composite index
    $table->index(['category', 'created_at'], 'category_date_idx');
    
    // Unique index
    $table->unique(['title'], 'unique_title');
    
    // Full-text index
    $table->fullTextIndex(['title', 'content'], 'search_fulltext');
    
    // Partial index (MySQL 8.0+)
    $table->partialIndex(['title'], 'active_titles', 'status = "active"');
});

$schema->createTable('analytics', function($table) {
    $table->increments('id');
    
    // Geographic data
    $table->point('location');          // POINT type for coordinates
    $table->polygon('area');            // POLYGON type for regions
    $table->lineString('route');        // LINESTRING type for paths
    
    // Large objects
    $table->mediumText('report');       // Up to 16MB text
    $table->longText('log_data');       // Up to 4GB text
    $table->mediumBlob('image');        // Up to 16MB binary
    $table->longBlob('video');          // Up to 4GB binary
    
    // Network data
    $table->ipAddress('client_ip');     // IPv4/IPv6
    $table->macAddress('device_mac');   // MAC address
    
    // JSON and document storage
    $table->json('config');             // JSON data
    $table->jsonb('metadata');          // Binary JSON (if supported)
    
    // Time-series data
    $table->timestamp('event_time', 6); // Microsecond precision
    $table->time('duration', 3);        // Millisecond precision
    $table->year('fiscal_year');        // Year only
});

// SimpleMDB validates all column names
try {
    $schema->string('user-name');  // ✅ Valid: hyphens allowed
    $schema->string('user_name');  // ✅ Valid: underscores allowed
    $schema->string('userName');   // ✅ Valid: camelCase allowed
    $schema->string('user name');  // ❌ Invalid: spaces not allowed
    $schema->string('select');     // ❌ Invalid: MySQL reserved word
} catch (SimpleMDB\Exceptions\SchemaException $e) {
    echo "Schema error: " . $e->getMessage();
}

// Length validation
try {
    $schema->string('title', 70000);     // ❌ Invalid: VARCHAR max is 65535
    $schema->decimal('price', 70, 2);    // ❌ Invalid: DECIMAL max precision is 65
    $schema->enum('status', []);         // ❌ Invalid: ENUM needs values
} catch (SimpleMDB\Exceptions\SchemaException $e) {
    echo "Validation error: " . $e->getMessage();
}

// Type compatibility checking
try {
    $schema->json('data')->unsigned();   // ❌ Invalid: JSON can't be unsigned
    $schema->text('content')->after('id'); // ✅ Valid: positioning modifier
    $schema->string('name')->invisible(); // ✅ Valid: MySQL 8.0+ feature
} catch (SimpleMDB\Exceptions\SchemaException $e) {
    echo "Modifier error: " . $e->getMessage();
}

// Batch operations for better performance
$schema->startBatch();

// Add multiple columns efficiently
$schema->string('first_name', 50);
$schema->string('last_name', 50);
$schema->string('email', 150);
$schema->date('birth_date');

// Execute all operations at once
$schema->createTable('users');
$schema->commitBatch();

$schema->createTable('user_activities', function($table) {
    $table->increments('id');
    $table->unsignedInteger('user_id');
    $table->string('activity_type', 50);
    $table->timestamp('created_at');
    
    // Optimized indexing strategy
    $table->index(['user_id', 'created_at'], 'user_timeline');      // Timeline queries
    $table->index(['activity_type', 'created_at'], 'type_timeline'); // Type filtering
    $table->index(['created_at'], 'created_at_idx');                 // Date range queries
});

use SimpleMDB\DatabaseFactory;
use SimpleMDB\SchemaBuilder;

// Connect to database
$db = DatabaseFactory::create('pdo', 'localhost', 'root', 'password', 'database');
$schema = new SchemaBuilder($db);

// Create modern table with enterprise features
$schema->increments('id')
       ->string('name')->comment('User full name')
       ->string('email')->unique()
       ->ipAddress('last_ip')->nullable()
       ->json('preferences')->nullable()
       ->enum('status', ['active', 'inactive'])->default('active')
       ->timestamps()
       ->softDeletes()
       ->createTable('users');

use SimpleMDB\Migrations\MigrationManager;

// Initialize migration manager
$migrations = new MigrationManager($db);

// Set migration directory (optional)
$migrations->setMigrationDirectory('./database/migrations');

// Set migration table name (optional)
$migrations->setMigrationTable('schema_migrations');

// Create new migration with intelligent template
$file = $migrations->create('create_users_table');
echo "Migration created: $file\n";

// Create with custom template
$file = $migrations->create('add_email_to_customers', [
    'template' => 'add_column',
    'table' => 'customers',
    'column' => 'email',
    'type' => 'string'
]);

// Run all pending migrations
$migrations->migrate();

// Run specific number of migrations
$migrations->migrate(5);

// Run migrations with output
$migrations->migrate(null, true); // true for verbose output

// Check migration status
$status = $migrations->status();
foreach ($status as $migration) {
    echo sprintf("%-40s %s\n", $migration['name'], $migration['status']);
}

// Check if migrations are pending
if ($migrations->hasPendingMigrations()) {
    echo "Pending migrations found!\n";
}

// Migration name: "create_users_table"
$migrations->create('create_users_table');


use SimpleMDB\Migrations\Migration;

class CreateUsersTable extends Migration
{
    public function up(): void
    {
        $this->createTable('users', function($table) {
            $table->increments('id');
            $table->string('name')->comment('Full name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->boolean('is_active')->default(true);
            $table->json('preferences')->nullable();
            $table->rememberToken();
            $table->timestamps();
            $table->softDeletes();
            
            $table->index(['email']);
            $table->index(['created_at']);
        });
    }
    
    public function down(): void
    {
        $this->dropIfExists('users');
    }
}

// Migration name: "add_email_to_customers"
$migrations->create('add_email_to_customers');


use SimpleMDB\Migrations\Migration;

class AddEmailToCustomers extends Migration
{
    public function up(): void
    {
        $this->addColumn('customers', function($table) {
            $table->string('email', 150)
                  ->unique()
                  ->comment('Customer email address')
                  ->after('name'); // Intelligent positioning
        });
    }
    
    public function down(): void
    {
        $this->dropColumn('customers', 'email');
    }
}

// Migration name: "add_email_index_to_users"
$migrations->create('add_email_index_to_users');


use SimpleMDB\Migrations\Migration;

class AddEmailIndexToUsers extends Migration
{
    public function up(): void
    {
        $this->addIndex('users', ['email'], 'users_email_index');
    }
    
    public function down(): void
    {
        $this->dropIndex('users', 'users_email_index');
    }
}

// Migration name: "modify_products_table"
$migrations->create('modify_products_table');


use SimpleMDB\Migrations\Migration;

class ModifyProductsTable extends Migration
{
    public function up(): void
    {
        $this->modifyTable('products', function($table) {
            // Add new columns
            $table->string('slug', 200)->unique()->after('name');
            $table->decimal('compare_price', 10, 2)->unsigned()->nullable()->after('price');
            $table->boolean('featured')->default(false)->after('active');
            $table->json('seo_metadata')->nullable();
            
            // Modify existing columns
            $table->modifyColumn('description', 'text', null, ['nullable' => true]);
            $table->modifyColumn('price', 'decimal', [10, 2], ['unsigned' => true]);
            
            // Add indexes
            $table->index(['slug']);
            $table->index(['featured', 'active']);
            $table->index(['price', 'compare_price']);
        });
    }
    
    public function down(): void
    {
        $this->modifyTable('products', function($table) {
            $table->dropColumn(['slug', 'compare_price', 'featured', 'seo_metadata']);
            $table->dropIndex('products_slug_index');
            $table->dropIndex('products_featured_active_index');
            $table->dropIndex('products_price_compare_price_index');
        });
    }
}

// Rollback last migration
$migrations->rollback();

// Rollback specific number of migrations
$migrations->rollback(3);

// Rollback to specific migration
$migrations->rollbackTo('20240101_120000_CreateUsersTable');

// Reset all migrations (dangerous!)
$migrations->reset();

// Detailed migration history
$history = $migrations->history();
foreach ($history as $migration) {
    echo sprintf(
        "%-40s %-10s %s\n",
        $migration['name'],
        $migration['status'],
        $migration['executed_at'] ?? 'Pending'
    );
}

// Check if specific migration exists
if ($migrations->hasMigration('create_users_table')) {
    echo "Users table migration exists\n";
}

// Get migration file path
$path = $migrations->getMigrationPath('create_users_table');

// Run migrations in transaction
$migrations->migrateInTransaction();

// Rollback migrations in transaction
$migrations->rollbackInTransaction(2);

// Dry run (show what would be executed)
$migrations->dryRun();

// Migration with seeding
class CreateCategoriesTable extends Migration
{
    public function up(): void
    {
        $this->createTable('categories', function($table) {
            $table->increments('id');
            $table->string('name', 100)->unique();
            $table->string('slug', 100)->unique();
            $table->text('description')->nullable();
            $table->boolean('active')->default(true);
            $table->timestamps();
        });
        
        // Seed initial data
        $this->seed();
    }
    
    public function down(): void
    {
        $this->dropIfExists('categories');
    }
    
    private function seed(): void
    {
        $categories = [
            ['name' => 'Technology', 'slug' => 'technology', 'description' => 'Tech products'],
            ['name' => 'Fashion', 'slug' => 'fashion', 'description' => 'Fashion items'],
            ['name' => 'Home', 'slug' => 'home', 'description' => 'Home products'],
        ];
        
        foreach ($categories as $category) {
            $this->insert('categories', $category);
        }
    }
}


use SimpleMDB\Migrations\Migration;

class ExampleMigration extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        // Migration code here
    }
    
    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        // Rollback code here
    }
}


use SimpleMDB\Migrations\Migration;

class CreateEcommerceTables extends Migration
{
    public function up(): void
    {
        // Create products table
        $this->createTable('products', function($table) {
            $table->increments('id');
            $table->string('sku', 50)->unique();
            $table->string('name', 200);
            $table->text('description')->nullable();
            $table->decimal('price', 10, 2)->unsigned();
            $table->json('attributes')->nullable();
            $table->boolean('active')->default(true);
            $table->timestamps();
            
            $table->index(['active', 'created_at']);
            $table->fullTextIndex(['name', 'description']);
        });
        
        // Create product_categories table
        $this->createTable('product_categories', function($table) {
            $table->increments('id');
            $table->unsignedInteger('product_id');
            $table->unsignedInteger('category_id');
            $table->timestamps();
            
            $table->unique(['product_id', 'category_id']);
            $table->foreignKey('product_id', 'products', 'id', 'CASCADE');
            $table->foreignKey('category_id', 'categories', 'id', 'CASCADE');
        });
        
        // Create product_reviews table
        $this->createTable('product_reviews', function($table) {
            $table->increments('id');
            $table->unsignedInteger('product_id');
            $table->unsignedInteger('user_id');
            $table->tinyInteger('rating')->unsigned();
            $table->text('comment')->nullable();
            $table->boolean('verified_purchase')->default(false);
            $table->timestamps();
            
            $table->index(['product_id', 'rating']);
            $table->index(['user_id', 'created_at']);
            $table->foreignKey('product_id', 'products', 'id', 'CASCADE');
            $table->foreignKey('user_id', 'users', 'id', 'CASCADE');
        });
    }
    
    public function down(): void
    {
        $this->dropIfExists('product_reviews');
        $this->dropIfExists('product_categories');
        $this->dropIfExists('products');
    }
}

// ✅ Good naming conventions
create_users_table
add_email_to_customers
modify_products_table
drop_old_logs_table
add_index_to_orders
remove_unused_columns_from_posts

// ❌ Poor naming conventions
fix_stuff
update_db
migration_v2
temp_changes

public function up(): void
{
    // ✅ Always check if table exists
    if (!$this->hasTable('users')) {
        $this->createTable('users', function($table) {
            // Table definition
        });
    }
    
    // ✅ Check if column exists before adding
    if (!$this->hasColumn('users', 'email')) {
        $this->addColumn('users', 'email', 'string', 150);
    }
    
    // ✅ Use transactions for multiple operations
    $this->beginTransaction();
    try {
        $this->addColumn('users', 'status', 'string', 20);
        $this->addIndex('users', ['status']);
        $this->commit();
    } catch (Exception $e) {
        $this->rollback();
        throw $e;
    }
}

public function down(): void
{
    // ✅ Always provide proper rollback
    $this->dropColumn('users', 'email');
    
    // ✅ Check before dropping
    if ($this->hasTable('temporary_table')) {
        $this->dropTable('temporary_table');
    }
    
    // ✅ Drop indexes before dropping columns
    $this->dropIndex('users', 'users_email_index');
    $this->dropColumn('users', 'email');
}

use SimpleMDB\Migrations\MigrationManager;

$migrations = new MigrationManager($db);

// Create intelligent migration
$file = $migrations->create('create_blog_posts_table');
// ✨ Generates context-aware template with modern data types

// Run migrations
$migrations->migrate();

// Check status
foreach ($migrations->status() as $migration) {
    echo "{$migration['name']}: {$migration['status']}\n";
}

use SimpleMDB\SimpleQuery;

// Complex queries with modern features
$posts = SimpleQuery::create()
    ->select(['id', 'title', 'status', 'created_at'])
    ->from('blog_posts')
    ->where('status IN ?', [['published', 'featured']])
    ->whereJsonContains('metadata->tags', 'php')
    ->orderBy('created_at DESC')
    ->limit(10)
    ->execute($db);

// Create polymorphic relationship in one line
$schema->increments('id')
       ->text('content')  
       ->morphs('commentable')    // Creates commentable_id + commentable_type + index
       ->timestamps()
       ->createTable('comments');

$schema->increments('id')
       ->string('title', 200)->comment('SEO title')->after('id')
       ->text('content')->nullable()
       ->enum('status', ['draft', 'published', 'archived'])->default('draft')
       ->json('metadata')->nullable()
       ->decimal('price', 10, 2)->unsigned()->nullable()
       ->boolean('featured')->default(false)
       ->ipAddress('author_ip')->nullable()
       ->macAddress('device_fingerprint')->nullable()
       ->uuid('external_id')->unique()
       ->timestamps()
       ->softDeletes()
       ->index(['status', 'featured'], 'status_featured_index')
       ->createTable('products');

class CreateEcommerceTablessMigration extends Migration 
{
    public function up(): void
    {
        // Products table with modern e-commerce features
        $this->createTable('products', function($table) {
            $table->increments('id');
            $table->string('sku', 50)->unique();
            $table->string('name');
            $table->text('description')->nullable();
            $table->decimal('price', 10, 2)->unsigned();
            $table->unsignedInteger('stock_quantity')->default(0);
            $table->json('attributes')->nullable();        // Color, size, etc.
            $table->enum('status', ['active', 'inactive', 'discontinued']);
            $table->timestamps();
            
            $table->index(['status', 'price']);
            $table->index(['name']); // Full-text search ready
        });
        
        // Orders with polymorphic address support
        $this->createTable('orders', function($table) {
            $table->increments('id');
            $table->uuid('order_number')->unique();
            $table->unsignedInteger('customer_id');
            $table->decimal('total_amount', 10, 2);
            $table->enum('status', ['pending', 'processing', 'shipped', 'delivered']);
            $table->morphs('billing_address');     // Polymorphic addresses
            $table->morphs('shipping_address');
            $table->ipAddress('order_ip');
            $table->timestamps();
            
            $table->foreignKey('customer_id', 'users', 'id');
        });
    }
}