# Database Architecture

**Table of Contents**

* Introduction
* Database Connection System
* Medoo ORM Overview
* Database Schema
* DB Operations
* Advanced Queries
* Best Practices
* Troubleshooting

***

**Introduction**

**PHPTRAVELS v10+** uses a robust database architecture built on MySQL/MariaDB with the Medoo PHP database framework. This lightweight ORM (Object-Relational Mapping) library provides a simple, secure, and efficient way to interact with the database while maintaining clean, readable code.

#### Why Medoo?

<figure><img src="/files/wGkjFsdZbFEBRLZr4wGq" alt=""><figcaption></figcaption></figure>

**Lightweight & Fast**

* Only \~60KB in size with zero dependencies
* PDO-based for optimal performance
* Minimal overhead compared to heavy ORMs

**Security First**

* Built-in SQL injection protection through prepared statements
* Automatic parameter binding and escaping
* No raw SQL strings in production code

**Developer Friendly**

* Intuitive array-based syntax
* Chainable methods for complex queries
* Comprehensive error handling
* Multi-database support (MySQL, MariaDB, PostgreSQL, SQLite)

***

### Database Connection System

#### Environment Configuration (.env)

PHPTRAVELS v10 uses environment variables for database configuration, ensuring security and portability across different environments (development, staging, production).

**Location:** `/v10/.env`

```ini
# Database Configuration
DB_TYPE=mysql
DB_HOST=localhost
DB_DATABASE=v10
DB_USERNAME=root
DB_PASSWORD=root
```

**Configuration Parameters:**

| Parameter     | Description                                        | Default   |
| ------------- | -------------------------------------------------- | --------- |
| `DB_TYPE`     | Database engine (mysql, mariadb, sqlite, pgsql)    | mysql     |
| `DB_HOST`     | Database server hostname or IP address             | localhost |
| `DB_DATABASE` | Name of the database                               | v10       |
| `DB_USERNAME` | Database user with appropriate permissions         | root      |
| `DB_PASSWORD` | User password (use strong passwords in production) | -         |

#### Connection Initialization (config.php)

The central configuration file loads environment variables and establishes the database connection globally.

**Location:** `/config.php`

```php
<?php

use Medoo\Medoo;

// Load environment variables from .env file
$env = parse_ini_file('.env');

// Initialize Medoo database connection
$db = new Medoo([
    'type'     => $env['DB_TYPE'] ?? 'mysql',
    'host'     => $env['DB_HOST'] ?? 'localhost',
    'database' => $env['DB_DATABASE'],
    'username' => $env['DB_USERNAME'],
    'password' => $env['DB_PASSWORD'],
    'charset'  => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'port'     => 3306,
    'prefix'   => '', // Optional table prefix
    'option'   => [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES => false
    ]
]);
```

**Connection Flow Diagram:**

```
┌─────────────────────────────────────────────────────────────┐
│                    Application Start                        │
└───────────────────────────┬─────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│   Load config.php (Included in index.php/module files)     │
└───────────────────────────┬─────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│         Read .env file using parse_ini_file()               │
│   (Loads DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD)   │
└───────────────────────────┬─────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│      Initialize new Medoo([...]) with credentials          │
│             Create global $db variable                      │
└───────────────────────────┬─────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│       Medoo establishes PDO connection to MySQL             │
│         (With error handling and UTF-8 charset)             │
└───────────────────────────┬─────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────┐
│     Global $db variable available across application        │
│           Ready for database operations                     │
└─────────────────────────────────────────────────────────────┘
```

#### Global Accessibility

Once initialized in `config.php`, the `$db` variable is globally accessible throughout the application:

```php
// In any PHP file that includes config.php
require_once 'config.php';

// $db is now available for database operations
$users = $db->select("users", "*");
```

#### Connection Error Handling

```php
try {
    $db = new Medoo([
        'type'     => $env['DB_TYPE'] ?? 'mysql',
        'host'     => $env['DB_HOST'] ?? 'localhost',
        'database' => $env['DB_DATABASE'],
        'username' => $env['DB_USERNAME'],
        'password' => $env['DB_PASSWORD'],
    ]);

    // Test connection
    $db->query("SELECT 1")->fetchAll();

} catch (PDOException $e) {
    error_log("Database Connection Error: " . $e->getMessage());
    die("Unable to connect to database. Please check your configuration.");
}
```

***

### Medoo ORM Overview

Medoo provides an elegant, array-based API for database operations. Instead of writing raw SQL, you work with PHP arrays and objects.

#### Core Concepts

**1. Array-Based Syntax**

```php
// Traditional SQL
$sql = "SELECT * FROM users WHERE email = ? AND status = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute(['user@example.com', 1]);

// Medoo approach
$user = $db->get("users", "*", [
    "email" => "user@example.com",
    "status" => 1
]);
```

**2. Automatic Parameter Binding** All values are automatically escaped and bound as prepared statement parameters, preventing SQL injection.

**3. Method Chaining** Complex queries can be built incrementally using method chaining for readability.

#### Medoo Methods Reference

| Method      | Purpose                           | Returns           |
| ----------- | --------------------------------- | ----------------- |
| `select()`  | Retrieve multiple rows            | Array of rows     |
| `get()`     | Retrieve single row               | Associative array |
| `insert()`  | Insert new record                 | PDOStatement      |
| `update()`  | Update existing records           | PDOStatement      |
| `delete()`  | Delete records                    | PDOStatement      |
| `replace()` | Replace record (INSERT or UPDATE) | PDOStatement      |
| `has()`     | Check if record exists            | Boolean           |
| `count()`   | Count rows matching criteria      | Integer           |
| `sum()`     | Calculate sum of column           | Number            |
| `avg()`     | Calculate average                 | Number            |
| `max()`     | Find maximum value                | Mixed             |
| `min()`     | Find minimum value                | Mixed             |
| `query()`   | Execute raw SQL                   | PDOStatement      |

***

### Database Schema

PHPTRAVELS v10 uses a comprehensive relational database schema with 30+ tables organized into logical groups.

#### Schema Overview

```
┌────────────────────────────────────────────────────────────────┐
│                    PHPTRAVELS v10 Database                      │
│                      Schema Architecture                        │
└────────────────────────────────────────────────────────────────┘

┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│ Core Tables     │  │ Booking Tables  │  │ Content Tables  │
├─────────────────┤  ├─────────────────┤  ├─────────────────┤
│ • users         │  │ • bookings      │  │ • blogs         │
│ • settings      │  │ • flights       │  │ • blog_cats     │
│ • modules       │  │ • hotels        │  │ • cms           │
│ • currencies    │  │ • tours         │  │ • email_tpl     │
│ • languages     │  │ • cars          │  │ • notification  │
│ • countries     │  │ • transfers     │  │ • pages         │
└─────────────────┘  └─────────────────┘  └─────────────────┘

┌─────────────────┐  ┌─────────────────┐ 
│ Payment Tables  │  │ Logging Tables  │
├─────────────────┤  ├─────────────────┤  
│ • transactions  │  │ • logs_bookings │
│ • credits       │  │ • logs_searches │
│ • invoices      │  │ • logs_users    │
│ • refunds       │  │ • logs_webhooks │
└─────────────────┘  └─────────────────┘

┌─────────────────┐  ┌─────────────────┐
│ Location Data   │  │ Reference Data  │
├─────────────────┤  ├─────────────────┤
│ • locations     │  │ • airports      │
│ • cities        │  │ • airlines      │
│ • destinations  │  │ • amenities     │
└─────────────────┘  └─────────────────┘
```

#### Core Tables

**1. users** - User authentication and profiles

```sql
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(50) UNIQUE NOT NULL,
  `first_name` varchar(100) NOT NULL,
  `last_name` varchar(100) NOT NULL,
  `email` varchar(255) UNIQUE NOT NULL,
  `password` varchar(255) NOT NULL,
  `phone` varchar(20) DEFAULT NULL,
  `country` varchar(100) DEFAULT NULL,
  `city` varchar(100) DEFAULT NULL,
  `address` text DEFAULT NULL,
  `state` varchar(100) DEFAULT NULL,
  `po_box` varchar(20) DEFAULT NULL,
  `user_type` enum('customer','agent','admin') DEFAULT 'customer',
  `status` tinyint(1) DEFAULT 1,
  `banned` tinyint(1) DEFAULT 0,
  `email_verified` tinyint(1) DEFAULT 0,
  `email_verification_token` varchar(100) DEFAULT NULL,
  `reset_password_token` varchar(100) DEFAULT NULL,
  `reset_password_expires` datetime DEFAULT NULL,
  `last_login` timestamp NULL DEFAULT NULL,
  `created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_email` (`email`),
  KEY `idx_user_id` (`user_id`),
  KEY `idx_user_type` (`user_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

**Key Fields:**

* `user_id`: Unique external identifier (UUID format)
* `password`: Hashed using password\_hash() with PASSWORD\_BCRYPT
* `user_type`: Role-based access control (customer/agent/admin)
* `status`: Active (1) or inactive (0) account
* `email_verified`: Email confirmation status

**2. settings** - Global application configuration

**3. modules** - Enabled/disabled booking modules

**4. currencies** - Supported currencies with exchange rates

**5. languages** - Multi-language support

#### Booking Tables

**bookings** - Master booking records

```sql
CREATE TABLE `bookings` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `invoice_id` varchar(255) UNIQUE NOT NULL,
  `booking_status` enum('confirmed','pending','cancelled') DEFAULT 'pending',
  `payment_status` enum('paid','unpaid','refunded') DEFAULT 'unpaid',
  `price_original` double NOT NULL,
  `price_markup` varchar(225) DEFAULT '',
  `agent_earning` varchar(255) DEFAULT '',
  `tax` text NOT NULL,
  `first_name` varchar(50) NOT NULL,
  `last_name` varchar(50) NOT NULL,
  `email` varchar(50) NOT NULL,
  `phone` varchar(15) NOT NULL,
  `adults` tinyint(4) DEFAULT 1,
  `childs` tinyint(4) DEFAULT 0,
  `infants` varchar(255) DEFAULT '',
  `booking_data` text NOT NULL,
  `transaction_id` varchar(255) DEFAULT '',
  `user_id` varchar(255) DEFAULT '',
  `payment_gateway` varchar(255) DEFAULT '',
  `module_type` varchar(255) DEFAULT 'hotels',
  `module` varchar(255) NOT NULL,
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_invoice` (`invoice_id`),
  KEY `idx_user` (`user_id`),
  KEY `idx_status` (`booking_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
```

#### Logging Tables

System maintains comprehensive audit logs:

* **logs\_bookings** - Booking lifecycle events
* **logs\_searches** - User search analytics
* **logs\_users** - Authentication and profile changes
* **logs\_webhooks** - External API webhook events

#### Scalability Design

The database schema is designed for horizontal scalability:

**Current Tables:** 30+ core tables **Expandable:** Schema supports unlimited growth through:

* Modular table design (add new booking types)
* Polymorphic relationships (flexible module system)
* JSON columns for dynamic data (booking\_data, user\_data)
* Partitioning support for large tables

***

### DB Operations

#### SELECT - Retrieving Data

**Basic Select - All Columns**

```php
// Get all users
$users = $db->select("users", "*");

// Result: Array of all user records
```

**Select Specific Columns**

```php
// Get only email and name
$users = $db->select("users", [
    "id",
    "first_name",
    "last_name",
    "email"
]);
```

**Select with WHERE Conditions**

```php
// Find user by email
$user = $db->get("users", "*", [
    "email" => "admin@phptravels.com"
]);

// Find all active users
$active_users = $db->select("users", "*", [
    "status" => 1,
    "banned" => 0
]);
```

**Select with Multiple Conditions (AND)**

```php
$users = $db->select("users", "*", [
    "user_type" => "agent",
    "status" => 1,
    "email_verified" => 1
]);

// Generated SQL (protected against injection):
// SELECT * FROM users WHERE user_type = 'agent' AND status = 1 AND email_verified = 1
```

**Select with OR Conditions**

```php
$users = $db->select("users", "*", [
    "OR" => [
        "user_type" => "admin",
        "user_type" => "agent"
    ]
]);
```

**Select with Comparison Operators**

```php
// Users created in last 30 days
$recent_users = $db->select("users", "*", [
    "created_at[>]" => date('Y-m-d H:i:s', strtotime('-30 days'))
]);

// Operators: [>], [>=], [<], [<=], [!] (not equal), [<>] (between)
```

**Select with LIKE (Pattern Matching)**

```php
// Find users with email ending in @gmail.com
$gmail_users = $db->select("users", "*", [
    "email[~]" => "%@gmail.com"
]);

// Operators: [~] (LIKE), [!~] (NOT LIKE)
```

**Select with LIMIT and ORDER**

```php
$latest_users = $db->select("users", "*", [
    "ORDER" => ["created_at" => "DESC"],
    "LIMIT" => 10
]);
```

**Select with Pagination**

```php
$page = 1;
$per_page = 20;
$offset = ($page - 1) * $per_page;

$users = $db->select("users", "*", [
    "LIMIT" => [$offset, $per_page],
    "ORDER" => ["id" => "ASC"]
]);
```

**Get Single Row**

```php
// Returns first matching row only
$user = $db->get("users", "*", [
    "email" => "user@example.com"
]);

// $user is associative array or null if not found
if ($user) {
    echo $user['first_name'];
}
```

#### INSERT - Creating Records

**Basic Insert**

```php
$db->insert("users", [
    "user_id" => uniqid('user_'),
    "first_name" => "John",
    "last_name" => "Doe",
    "email" => "john@example.com",
    "password" => password_hash("secure123", PASSWORD_BCRYPT),
    "user_type" => "customer",
    "status" => 1
]);

// Get inserted ID
$new_user_id = $db->id();
```

**Insert with Current Timestamp**

```php
$db->insert("bookings", [
    "invoice_id" => 'INV-' . time(),
    "user_id" => $user_id,
    "booking_status" => "pending",
    "payment_status" => "unpaid",
    "price_original" => 150.00,
    "created_at" => Medoo::raw("NOW()")
]);
```

**Bulk Insert**

```php
$db->insert("logs_searches", [
    [
        "user_id" => 1,
        "module" => "hotels",
        "search_query" => json_encode($params),
        "created_at" => date('Y-m-d H:i:s')
    ],
    [
        "user_id" => 2,
        "module" => "flights",
        "search_query" => json_encode($params2),
        "created_at" => date('Y-m-d H:i:s')
    ]
]);
```

#### UPDATE - Modifying Records

**Basic Update**

```php
$db->update("users", [
    "first_name" => "Jane",
    "last_name" => "Smith"
], [
    "id" => 5
]);

// Returns PDOStatement
```

**Update with Multiple Conditions**

```php
$db->update("users", [
    "email_verified" => 1,
    "email_verification_token" => null
], [
    "email" => "user@example.com",
    "email_verification_token" => $token
]);
```

**Increment/Decrement Values**

```php
// Increment views
$db->update("blogs", [
    "views[+]" => 1  // Increment by 1
], [
    "id" => $blog_id
]);

// Decrement credits
$db->update("credits", [
    "balance[-]" => 50.00  // Decrement by 50
], [
    "user_id" => $user_id
]);
```

**Update with Raw SQL**

```php
$db->update("users", [
    "last_login" => Medoo::raw("NOW()")
], [
    "id" => $user_id
]);
```

#### DELETE - Removing Records

**Basic Delete**

```php
$db->delete("users", [
    "id" => 10
]);
```

**Delete with Multiple Conditions**

```php
// Delete inactive users older than 1 year
$db->delete("users", [
    "status" => 0,
    "created_at[<]" => date('Y-m-d', strtotime('-1 year'))
]);
```

**Soft Delete (Recommended)**

```php
// Instead of deleting, mark as deleted
$db->update("users", [
    "status" => 0,
    "deleted_at" => date('Y-m-d H:i:s')
], [
    "id" => $user_id
]);
```

#### EXISTS - Check Record Existence

**Check if User Exists**

```php
$exists = $db->has("users", [
    "email" => "test@example.com"
]);

if ($exists) {
    // Email already registered
}
```

#### COUNT - Counting Records

**Simple Count**

```php
$total_users = $db->count("users");
```

**Count with Conditions**

```php
$active_agents = $db->count("users", [
    "user_type" => "agent",
    "status" => 1
]);
```

***

### Advanced Queries

#### JOIN Operations

**INNER JOIN**

```php
$results = $db->select("bookings", [
    "[>]users" => ["user_id" => "user_id"]
], [
    "bookings.invoice_id",
    "bookings.booking_status",
    "bookings.created_at",
    "users.first_name",
    "users.last_name",
    "users.email"
], [
    "bookings.booking_status" => "confirmed"
]);
```

**LEFT JOIN**

```php
$results = $db->select("users", [
    "[<]bookings" => ["user_id" => "user_id"]
], [
    "users.email",
    "users.first_name",
    "bookings.invoice_id(booking_id)",
    "bookings.created_at(booking_date)"
]);
```

**Multiple JOINS**

```php
$results = $db->select("bookings", [
    "[>]users" => ["user_id" => "user_id"],
    "[>]transactions" => ["id" => "booking_id"]
], [
    "bookings.invoice_id",
    "users.email",
    "transactions.amount",
    "transactions.payment_gateway"
]);
```

#### Aggregation Functions

**SUM**

```php
$total_revenue = $db->sum("bookings", "price_markup", [
    "payment_status" => "paid",
    "created_at[>]" => date('Y-m-01')
]);

echo "Revenue this month: $" . number_format($total_revenue, 2);
```

**AVERAGE**

```php
$avg_booking_value = $db->avg("bookings", "price_original", [
    "booking_status" => "confirmed"
]);
```

**MAX/MIN**

```php
$highest_booking = $db->max("bookings", "price_original");
$lowest_booking = $db->min("bookings", "price_original");
```

#### GROUP BY and HAVING

**Group By with Count**

```php
$results = $db->select("bookings", [
    "module",
    "COUNT(*) AS total_bookings"
], [
    "GROUP" => "module",
    "ORDER" => ["total_bookings" => "DESC"]
]);
```

#### Raw SQL Queries

For complex queries not covered by Medoo methods:

```php
// Execute raw query
$stmt = $db->query("
    SELECT
        DATE(created_at) as date,
        COUNT(*) as bookings,
        SUM(price_markup) as revenue
    FROM bookings
    WHERE payment_status = 'paid'
    GROUP BY DATE(created_at)
    ORDER BY date DESC
    LIMIT 30
");

$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
```

***

### Best Practices

#### 1. Security

**Always Use Prepared Statements**

```php
// NEVER concatenate user input into queries
// BAD:
$user = $db->query("SELECT * FROM users WHERE email = '$email'")->fetch();

// GOOD:
$user = $db->get("users", "*", ["email" => $email]);
```

**Hash Passwords Properly**

```php
// During registration
$hashed = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
$db->insert("users", ["email" => $email, "password" => $hashed]);

// During login verification
$user = $db->get("users", "*", ["email" => $email]);
if ($user && password_verify($password, $user['password'])) {
    // Login successful
}
```

**Validate Input**

```php
// Sanitize and validate before database operations
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    die("Invalid email format");
}
```

#### 2. Performance Optimization

**Use Indexes**

```sql
-- Add indexes to frequently queried columns
CREATE INDEX idx_user_email ON users(email);
CREATE INDEX idx_booking_invoice ON bookings(invoice_id);
CREATE INDEX idx_booking_status ON bookings(booking_status, payment_status);
```

**Select Only Required Columns**

```php
// Instead of SELECT *
$users = $db->select("users", [
    "id",
    "first_name",
    "email"
], ["status" => 1]);
```

**Use LIMIT for Large Tables**

```php
// Paginate results
$bookings = $db->select("bookings", "*", [
    "LIMIT" => [0, 50],
    "ORDER" => ["created_at" => "DESC"]
]);
```

**Cache Frequent Queries**

```php
// Cache settings in session
if (!isset($_SESSION['app_settings'])) {
    $_SESSION['app_settings'] = $db->get("settings", "*", ["id" => 1]);
}
$settings = $_SESSION['app_settings'];
```

#### 3. Error Handling

**Always Use Try-Catch**

```php
try {
    $db->insert("users", [
        "email" => $email,
        "password" => $hashed_password
    ]);

    $user_id = $db->id();

} catch (PDOException $e) {
    // Log error
    error_log("Database Error: " . $e->getMessage());

    // Show user-friendly message
    die("Registration failed. Please try again.");
}
```

**Check for Errors**

```php
$result = $db->update("users", ["status" => 1], ["id" => $user_id]);

if ($db->error()[2]) {
    // Error occurred
    error_log("Update failed: " . $db->error()[2]);
}
```

#### 4. Data Integrity

**Use Transactions**

```php
try {
    // Start transaction
    $db->action(function($db) {

        // Insert booking
        $db->insert("bookings", $booking_data);
        $booking_id = $db->id();

        // Insert transaction
        $db->insert("transactions", [
            "booking_id" => $booking_id,
            "amount" => $amount,
            "status" => "completed"
        ]);

        // Update user credits
        $db->update("credits", [
            "balance[-]" => $amount
        ], [
            "user_id" => $user_id
        ]);

        // All queries succeed or all rollback
    });

} catch (Exception $e) {
    // Transaction rolled back automatically
    error_log("Transaction failed: " . $e->getMessage());
}
```

#### 5. Code Organization

**Create Repository Classes**

```php
class UserRepository {
    private $db;

    public function __construct($db) {
        $this->db = $db;
    }

    public function findByEmail($email) {
        return $this->db->get("users", "*", ["email" => $email]);
    }

    public function create($data) {
        $this->db->insert("users", $data);
        return $this->db->id();
    }

    public function updateLastLogin($user_id) {
        return $this->db->update("users", [
            "last_login" => Medoo::raw("NOW()")
        ], ["id" => $user_id]);
    }
}

// Usage
$userRepo = new UserRepository($db);
$user = $userRepo->findByEmail("admin@phptravels.com");
```

***

### Troubleshooting

#### Connection Issues

**Problem: "Access denied" Error**

```
Solution:
1. Verify .env credentials match MySQL user
2. Grant proper permissions:
   GRANT ALL PRIVILEGES ON v10.* TO 'username'@'localhost';
   FLUSH PRIVILEGES;
```

**Problem: "Database not found"**

```
Solution:
1. Create database manually:
   CREATE DATABASE v10 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
2. Run installation wizard at /install
```

**Problem: PDO Extension Not Loaded**

```
Solution:
1. Enable PDO in php.ini:
   extension=pdo_mysql
2. Restart Apache/Nginx
3. Verify: php -m | grep pdo
```

#### Query Issues

**Problem: Empty Results**

```php
// Debug query
$users = $db->select("users", "*", ["status" => 1]);
echo $db->last(); // Shows generated SQL
print_r($db->error()); // Shows any errors
```

**Problem: Slow Queries**

```php
// Enable query logging
$db->query("SET profiling = 1");
// Execute your queries
$profiles = $db->query("SHOW PROFILES")->fetchAll();
print_r($profiles);
```

#### Data Integrity

**Problem: Duplicate Entries**

```php
// Use UNIQUE constraints or check before insert
if (!$db->has("users", ["email" => $email])) {
    $db->insert("users", $data);
}
```

**Problem: Foreign Key Constraints**

```
Solution:
1. Ensure parent record exists before inserting child
2. Use ON DELETE CASCADE for automatic cleanup
3. Disable temporarily for bulk operations:
   SET FOREIGN_KEY_CHECKS=0;
```

#### Debugging Tools

**View Generated SQL**

```php
$db->select("users", "*", ["status" => 1]);
echo $db->last(); // Outputs: SELECT * FROM users WHERE status = 1
```

**Check Connection Status**

```php
$info = $db->info();
print_r($info);
// Returns: ['server' => ..., 'driver' => 'mysql', 'client' => ...]
```

**Error Information**

```php
$error = $db->error();
print_r($error);
// [0] => SQLSTATE code
// [1] => Driver error code
// [2] => Error message
```

***

### Additional Resources

**Official Medoo Documentation** <https://medoo.in/doc>

**PHPTRAVELS Database Migrations** Location: `/install/db.sql`

**Database Backup Command**

```bash
mysqldump -u root -p v10 > backup_$(date +%Y%m%d).sql
```

**Database Restore Command**

```bash
mysql -u root -p v10 < backup_20260109.sql
```

***

### Summary

The PHPTRAVELS v10 database architecture provides:

* Secure connection management via environment variables
* Efficient ORM operations through Medoo framework
* Scalable schema design supporting 30+ tables
* Comprehensive DB operations with array-based syntax
* Advanced query capabilities (JOINs, aggregations, transactions)
* Built-in security through prepared statements
* Performance optimization through indexing and caching
* Robust error handling and debugging tools

This architecture ensures data integrity, security, and performance while maintaining developer productivity through clean, readable code.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.phptravels.com/support/for-developers/database-architecture.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
