تخطَّ إلى المحتوى

أدوات قاعدة البيانات

توفر مساحة اسم Xmf\Database فئات لتبسيط مهام صيانة قاعدة البيانات المرتبطة بتثبيت وتحديث وحدات XOOPS. تتعامل هذه الأدوات مع ترحيل المخطط وتعديلات الجداول وتحميل البيانات الأولية.

تشمل أدوات قاعدة البيانات:

  • Tables - بناء وتنفيذ عبارات DDL لتعديلات الجدول
  • Migrate - مزامنة مخطط قاعدة البيانات بين إصدارات الوحدة
  • TableLoad - تحميل البيانات الأولية في الجداول

تبسط فئة Tables إنشاء وتعديل جداول قاعدة البيانات. تبني طابور عمل لعبارات DDL (Data Definition Language) التي يتم تنفيذها معاً.

  • تحميل المخطط الحالي من الجداول الموجودة
  • قائمة التغييرات بدون تنفيذ فوري
  • تأخذ في الاعتبار الحالة الحالية عند تحديد العمل المراد إجراؤه
  • التعامل التلقائي مع بادئة جدول XOOPS
use Xmf\Database\Tables;
// Create a new Tables instance
$tables = new Tables();
// Load an existing table or start new schema
$tables->addTable('mymodule_items');
// For existing tables only (fails if table doesn't exist)
$tables->useTable('mymodule_items');
$tables = new Tables();
$tables->addTable('mymodule_old_name');
$tables->renameTable('mymodule_old_name', 'mymodule_new_name');
$tables->executeQueue();
$tables->addTable('mymodule_items');
$tables->setTableOptions('mymodule_items', 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4');
$tables->executeQueue();
$tables->addTable('mymodule_temp');
$tables->dropTable('mymodule_temp');
$tables->executeQueue();
// Copy structure only
$tables->copyTable('mymodule_items', 'mymodule_items_backup', false);
// Copy structure and data
$tables->copyTable('mymodule_items', 'mymodule_items_backup', true);
$tables->executeQueue();
$tables = new Tables();
$tables->addTable('mymodule_items');
$tables->addColumn(
'mymodule_items',
'status',
"TINYINT(1) NOT NULL DEFAULT '1'"
);
$tables->executeQueue();
$tables->useTable('mymodule_items');
// Change column attributes
$tables->alterColumn(
'mymodule_items',
'title',
"VARCHAR(255) NOT NULL DEFAULT ''"
);
// Rename and modify column
$tables->alterColumn(
'mymodule_items',
'old_column_name',
"VARCHAR(100) NOT NULL",
'new_column_name'
);
$tables->executeQueue();

الحصول على خصائص العمود

Section titled “الحصول على خصائص العمود”
$tables->useTable('mymodule_items');
$attributes = $tables->getColumnAttributes('mymodule_items', 'title');
// Returns: "VARCHAR(255) NOT NULL DEFAULT ''"
$tables->useTable('mymodule_items');
$tables->dropColumn('mymodule_items', 'obsolete_field');
$tables->executeQueue();

الحصول على فهارس الجدول

Section titled “الحصول على فهارس الجدول”
$tables->useTable('mymodule_items');
$indexes = $tables->getTableIndexes('mymodule_items');
// Returns array like:
// [
// 'PRIMARY' => ['columns' => 'item_id', 'unique' => true],
// 'idx_category' => ['columns' => 'category_id', 'unique' => false]
// ]
$tables->addTable('mymodule_items');
$tables->addPrimaryKey('mymodule_items', 'item_id');
// Composite primary key
$tables->addPrimaryKey('mymodule_item_tags', 'item_id, tag_id');
$tables->executeQueue();
$tables->useTable('mymodule_items');
// Simple index
$tables->addIndex('idx_category', 'mymodule_items', 'category_id');
// Unique index
$tables->addIndex('idx_slug', 'mymodule_items', 'slug', true);
// Composite index
$tables->addIndex('idx_cat_status', 'mymodule_items', 'category_id, status');
$tables->executeQueue();
$tables->useTable('mymodule_items');
$tables->dropIndex('idx_old_index', 'mymodule_items');
$tables->executeQueue();

حذف جميع الفهارس غير الأساسية

Section titled “حذف جميع الفهارس غير الأساسية”
// Useful for cleaning up auto-generated index names
$tables->dropIndexes('mymodule_items');
$tables->executeQueue();
$tables->dropPrimaryKey('mymodule_items');
$tables->executeQueue();
$tables->useTable('mymodule_categories');
$tables->insert('mymodule_categories', [
'category_id' => 1,
'name' => 'General',
'weight' => 0
]);
// Without automatic quoting (for expressions)
$tables->insert('mymodule_logs', [
'created' => 'NOW()',
'message' => "'Test message'"
], false);
$tables->executeQueue();
$tables->useTable('mymodule_items');
// Update with criteria object
$criteria = new Criteria('status', 0);
$tables->update('mymodule_items', ['status' => 1], $criteria);
// Update with string criteria
$tables->update('mymodule_items', ['hits' => 0], 'hits IS NULL');
$tables->executeQueue();
$tables->useTable('mymodule_items');
// Delete with criteria
$criteria = new Criteria('status', -1);
$tables->delete('mymodule_items', $criteria);
// Delete with string criteria
$tables->delete('mymodule_items', 'created < DATE_SUB(NOW(), INTERVAL 1 YEAR)');
$tables->executeQueue();
$tables->useTable('mymodule_cache');
$tables->truncate('mymodule_cache');
$tables->executeQueue();
// Normal execution (respects HTTP method safety)
$result = $tables->executeQueue();
// Force execution even on GET requests
$result = $tables->executeQueue(true);
if (!$result) {
echo 'Error: ' . $tables->getLastError();
}
// Clear queue without executing
$tables->resetQueue();
// Add custom SQL to the queue
$tables->addToQueue('ALTER TABLE ' . $GLOBALS['xoopsDB']->prefix('mymodule_items') . ' CONVERT TO CHARACTER SET utf8mb4');
$tables->executeQueue();
$tables = new Tables();
if (!$tables->addTable('mymodule_items')) {
$error = $tables->getLastError();
$errno = $tables->getLastErrNo();
// Handle error
}

تبسط فئة Migrate مزامنة تغييرات قاعدة البيانات بين إصدارات الوحدة. تمتد إلى Tables مع مقارنة المخطط والمزامنة التلقائية.

use Xmf\Database\Migrate;
// Create migrate instance for a module
$migrate = new Migrate('mymodule');
// Synchronize database with target schema
$migrate->synchronizeSchema();

يُستدعى عادة في دالة xoops_module_pre_update_* الخاصة بالوحدة:

function xoops_module_pre_update_mymodule($module, $previousVersion)
{
$migrate = new \Xmf\Database\Migrate('mymodule');
// Perform any pre-sync actions (renames, etc.)
// ...
// Synchronize schema
return $migrate->synchronizeSchema();
}

لقواعد البيانات الكبيرة أو ترحيلات سطر الأوامر:

$migrate = new Migrate('mymodule');
$statements = $migrate->getSynchronizeDDL();
// Execute statements in batches or from CLI
foreach ($statements as $sql) {
// Process each statement
}

تتطلب بعض التغييرات معالجة صريحة قبل المزامنة. قم بتوسيع Migrate للترحيلات المعقدة:

class MyModuleMigrate extends \Xmf\Database\Migrate
{
public function preSyncActions()
{
// Rename a table before sync
$this->useTable('mymodule_old_name');
$this->renameTable('mymodule_old_name', 'mymodule_new_name');
$this->executeQueue();
// Rename a column
$this->useTable('mymodule_items');
$this->alterColumn(
'mymodule_items',
'old_column',
'VARCHAR(255) NOT NULL',
'new_column'
);
$this->executeQueue();
}
}
// Usage
$migrate = new MyModuleMigrate('mymodule');
$migrate->preSyncActions();
$migrate->synchronizeSchema();

الحصول على المخطط الحالي

Section titled “الحصول على المخطط الحالي”
$migrate = new Migrate('mymodule');
$currentSchema = $migrate->getCurrentSchema();

الحصول على المخطط الهدف

Section titled “الحصول على المخطط الهدف”
$targetSchema = $migrate->getTargetDefinitions();

لمطوري الوحدات لالتقاط المخطط بعد تغييرات قاعدة البيانات:

$migrate = new Migrate('mymodule');
$migrate->saveCurrentSchema();
// Saves schema to module's sql/migrate.yml

ملاحظة المطور: قم دائماً بإجراء التغييرات على قاعدة البيانات أولاً، ثم قم بتشغيل saveCurrentSchema(). لا تقم بتحرير ملف المخطط المُنشأ يدويًا.

تبسط فئة TableLoad تحميل البيانات الأولية في الجداول. مفيدة لتوطين الجداول بالبيانات الافتراضية أثناء تثبيت الوحدة.

تحميل البيانات من المصفوفات

Section titled “تحميل البيانات من المصفوفات”
use Xmf\Database\TableLoad;
$data = [
['category_id' => 1, 'name' => 'General', 'weight' => 0],
['category_id' => 2, 'name' => 'News', 'weight' => 10],
['category_id' => 3, 'name' => 'Events', 'weight' => 20]
];
$count = TableLoad::loadTableFromArray('mymodule_categories', $data);
echo "Inserted {$count} rows";
// Load from YAML file
$count = TableLoad::loadTableFromYamlFile(
'mymodule_categories',
XOOPS_ROOT_PATH . '/modules/mymodule/sql/categories.yml'
);

صيغة YAML:

-
category_id: 1
name: General
weight: 0
-
category_id: 2
name: News
weight: 10
// Count all rows
$total = TableLoad::countRows('mymodule_items');
// Count with criteria
$criteria = new Criteria('status', 1);
$activeCount = TableLoad::countRows('mymodule_items', $criteria);
// Extract all rows
$rows = TableLoad::extractRows('mymodule_items');
// Extract with criteria
$criteria = new Criteria('category_id', 5);
$rows = TableLoad::extractRows('mymodule_items', $criteria);
// Skip certain columns
$rows = TableLoad::extractRows('mymodule_items', null, ['password', 'token']);
// Save all data
TableLoad::saveTableToYamlFile(
'mymodule_categories',
'/path/to/categories.yml'
);
// Save filtered data
$criteria = new Criteria('is_default', 1);
TableLoad::saveTableToYamlFile(
'mymodule_settings',
'/path/to/default_settings.yml',
$criteria
);
// Save without certain columns
TableLoad::saveTableToYamlFile(
'mymodule_items',
'/path/to/items.yml',
null,
['created', 'modified']
);
// Empty a table
$affectedRows = TableLoad::truncateTable('mymodule_cache');
$modversion['sqlfile']['mysql'] = 'sql/mysql.sql';
$modversion['tables'] = [
'mymodule_items',
'mymodule_categories',
'mymodule_settings'
];
<?php
use Xmf\Database\Migrate;
use Xmf\Database\Tables;
use Xmf\Database\TableLoad;
function xoops_module_pre_update_mymodule($module, $previousVersion)
{
// Create custom migrate class
$migrate = new MyModuleMigrate('mymodule');
// Handle version-specific migrations
if ($previousVersion < 120) {
// Version 1.2.0 renamed a table
$migrate->renameOldTable();
}
if ($previousVersion < 130) {
// Version 1.3.0 renamed a column
$migrate->renameOldColumn();
}
// Synchronize schema
return $migrate->synchronizeSchema();
}
function xoops_module_update_mymodule($module, $previousVersion)
{
// Post-update data migrations
if ($previousVersion < 130) {
// Load new default settings
TableLoad::loadTableFromYamlFile(
'mymodule_settings',
XOOPS_ROOT_PATH . '/modules/mymodule/sql/new_settings.yml'
);
}
return true;
}
class MyModuleMigrate extends Migrate
{
public function renameOldTable()
{
if ($this->useTable('mymodule_posts')) {
$this->renameTable('mymodule_posts', 'mymodule_items');
$this->executeQueue();
}
}
public function renameOldColumn()
{
if ($this->useTable('mymodule_items')) {
$this->alterColumn(
'mymodule_items',
'post_title',
"VARCHAR(255) NOT NULL DEFAULT ''",
'title'
);
$this->executeQueue();
}
}
}
الطريقةالوصف
addTable($table)تحميل أو إنشاء مخطط الجدول
useTable($table)تحميل الجدول الموجود فقط
renameTable($table, $newName)قائمة إعادة تسمية الجدول
setTableOptions($table, $options)قائمة تغيير خيارات الجدول
dropTable($table)قائمة إسقاط الجدول
copyTable($table, $newTable, $withData)قائمة نسخ الجدول
addColumn($table, $column, $attributes)قائمة إضافة العمود
alterColumn($table, $column, $attributes, $newName)قائمة تعديل العمود
getColumnAttributes($table, $column)الحصول على تعريف العمود
dropColumn($table, $column)قائمة إسقاط العمود
getTableIndexes($table)الحصول على تعاريف الفهارس
addPrimaryKey($table, $column)قائمة المفتاح الأساسي
`addIndex($name, $table,