From 13c32e9e937627aa93e5f79a3be3eb16fcfdfdfd Mon Sep 17 00:00:00 2001 From: "Kamshory, MT" Date: Sat, 26 Oct 2024 07:14:39 +0700 Subject: [PATCH] Add PicoDatabaseUtilSqlite --- manual/includes/_sqlite.md | 5 +- manual/index.html | 5 +- src/Database/PicoSqlite.php | 97 ---- src/Util/Database/PicoDatabaseUtilMySql.php | 24 +- .../Database/PicoDatabaseUtilPostgreSql.php | 22 +- src/Util/Database/PicoDatabaseUtilSqlite.php | 423 ++++++++++++++++++ tests/sqlite.php | 78 +++- tutorial.md | 5 +- 8 files changed, 532 insertions(+), 127 deletions(-) create mode 100644 src/Util/Database/PicoDatabaseUtilSqlite.php diff --git a/manual/includes/_sqlite.md b/manual/includes/_sqlite.md index d82f30e..7f6f1d6 100644 --- a/manual/includes/_sqlite.md +++ b/manual/includes/_sqlite.md @@ -197,6 +197,7 @@ $sqlite->delete('users', $conditions); use MagicObject\Database\PicoSqlite; use MagicObject\MagicObject; +use MagicObject\Util\Database\PicoDatabaseUtilSqlite; require_once dirname(__DIR__) . "/vendor/autoload.php"; @@ -386,8 +387,8 @@ try $album = new Album(null, $database); // create table if not exists - $tableStructure = $database->showCreateTable($album, true); - + $util = new PicoDatabaseUtilSqlite(); + $tableStructure = $util->showCreateTable($album, true); $database->query($tableStructure); $album->setAlbumId("1235"); diff --git a/manual/index.html b/manual/index.html index b6e4567..fd8846a 100644 --- a/manual/index.html +++ b/manual/index.html @@ -10214,6 +10214,7 @@

Entity with PicoSqlite

use MagicObject\Database\PicoSqlite; use MagicObject\MagicObject; +use MagicObject\Util\Database\PicoDatabaseUtilSqlite; require_once dirname(__DIR__) . "/vendor/autoload.php"; @@ -10403,8 +10404,8 @@

Entity with PicoSqlite

$album = new Album(null, $database); // create table if not exists - $tableStructure = $database->showCreateTable($album, true); - + $util = new PicoDatabaseUtilSqlite(); + $tableStructure = $util->showCreateTable($album, true); $database->query($tableStructure); $album->setAlbumId("1235"); diff --git a/src/Database/PicoSqlite.php b/src/Database/PicoSqlite.php index 3273f3b..68c58d3 100644 --- a/src/Database/PicoSqlite.php +++ b/src/Database/PicoSqlite.php @@ -2,11 +2,8 @@ namespace MagicObject\Database; -use MagicObject\MagicObject; use PDO; use PDOException; -use ReflectionClass; -use ReflectionProperty; /** * Class PicoSqlite @@ -184,100 +181,6 @@ public function delete($tableName, $conditions) { return $stmt->execute(); } - - /** - * Generates a SQL CREATE TABLE query based on the provided class annotations. - * - * This function inspects the given class for its properties and their annotations - * to construct a SQL statement that can be used to create a corresponding table in a database. - * It extracts the table name from the `@Table` annotation and processes each property - * to determine the column definitions from the `@Column` annotations. - * - * @param MagicObject $entity The instance of the class whose properties will be used - * to generate the table structure. - * @param bool $ifNotExists If true, the query will include an "IF NOT EXISTS" clause. - * @return string The generated SQL CREATE TABLE query. - * - * @throws ReflectionException If the class does not exist or is not accessible. - */ - function showCreateTable($entity, $ifNotExists = false) { - $tableInfo = $entity->tableInfo(); - $tableName = $tableInfo->getTableName(); - - // Start building the CREATE TABLE query - if($ifNotExists) - { - $condition = " IF NOT EXISTS"; - } - else - { - $condition = ""; - } - $query = "CREATE TABLE$condition $tableName (\n"; - - // Define primary key - $primaryKey = null; - - $pKeys = $tableInfo->getPrimaryKeys(); - if(isset($pKeys) && is_array($pKeys) && !empty($pKeys)) - { - $pKeyArr = []; - $pkVals = array_values($pKeys); - foreach($pkVals as $pk) - { - $pKeyArr[] = $pk['name']; - } - $primaryKey = implode(", ", $pKeyArr); - } - - foreach ($tableInfo->getColumns() as $column) { - - $columnName = $column['name']; - $columnType = $column['type']; - $length = isset($column['length']) ? $column['length'] : null; - $nullable = (isset($column['nullable']) && $column['nullable'] === 'true') ? 'NULL' : 'NOT NULL'; - $defaultValue = isset($column['defaultValue']) ? "DEFAULT '{$column['defaultValue']}'" : ''; - - // Convert column type for SQL - $columnType = strtolower($columnType); // Convert to lowercase for case-insensitive comparison - - if (strpos($columnType, 'varchar') !== false) { - $sqlType = "VARCHAR($length)"; - } elseif ($columnType === 'int') { - $sqlType = 'INT'; - } elseif ($columnType === 'float') { - $sqlType = 'FLOAT'; - } elseif ($columnType === 'text') { - $sqlType = 'TEXT'; - } elseif ($columnType === 'longtext') { - $sqlType = 'LONGTEXT'; - } elseif ($columnType === 'date') { - $sqlType = 'DATE'; - } elseif ($columnType === 'timestamp') { - $sqlType = 'TIMESTAMP'; - } elseif ($columnType === 'tinyint(1)') { - $sqlType = 'TINYINT(1)'; - } else { - $sqlType = 'VARCHAR(255)'; // Fallback type - } - - // Add to query - $query .= " $columnName $sqlType $nullable,\n"; - - } - - // Remove the last comma and add primary key constraint - $query = rtrim($query, ",\n") . "\n"; - - if ($primaryKey) { - $query = rtrim($query, ",\n"); - $query .= ",\n PRIMARY KEY ($primaryKey)\n"; - } - - $query .= ");"; - - return str_replace("\n", "\r\n", $query); - } } diff --git a/src/Util/Database/PicoDatabaseUtilMySql.php b/src/Util/Database/PicoDatabaseUtilMySql.php index ac045a5..0ddbd5f 100644 --- a/src/Util/Database/PicoDatabaseUtilMySql.php +++ b/src/Util/Database/PicoDatabaseUtilMySql.php @@ -50,12 +50,12 @@ class PicoDatabaseUtilMySql extends PicoDatabaseUtilBase implements PicoDatabase * Retrieves a list of columns for a specified table. * * @param PicoDatabase $database Database connection. - * @param string $picoTableName Table name. + * @param string $tableName Table name. * @return array An array of column details. */ - public function getColumnList($database, $picoTableName) + public function getColumnList($database, $tableName) { - $sql = "SHOW COLUMNS FROM $picoTableName"; + $sql = "SHOW COLUMNS FROM $tableName"; return $database->fetchAll($sql); } @@ -67,20 +67,20 @@ public function getColumnList($database, $picoTableName) * "DROP TABLE IF EXISTS". It also handles the definition of primary keys if present. * * @param PicoTableInfo $tableInfo The information about the table, including column details and primary keys. - * @param string $picoTableName The name of the table for which the structure is being generated. + * @param string $tableName The name of the table for which the structure is being generated. * @param bool $createIfNotExists Whether to add "IF NOT EXISTS" in the CREATE statement (default is false). * @param bool $dropIfExists Whether to add "DROP TABLE IF EXISTS" before the CREATE statement (default is false). * @param string|null $engine The storage engine to use for the table (optional, default is null). * @param string|null $charset The character set to use for the table (optional, default is null). * @return string The SQL statement to create the table, including column definitions and primary keys. */ - public function dumpStructure($tableInfo, $picoTableName, $createIfNotExists = false, $dropIfExists = false, $engine = 'InnoDB', $charset = 'utf8mb4') + public function dumpStructure($tableInfo, $tableName, $createIfNotExists = false, $dropIfExists = false, $engine = 'InnoDB', $charset = 'utf8mb4') { $query = array(); $columns = array(); if($dropIfExists) { - $query[] = "-- DROP TABLE IF EXISTS `$picoTableName`;"; + $query[] = "-- DROP TABLE IF EXISTS `$tableName`;"; $query[] = ""; } $createStatement = ""; @@ -93,7 +93,7 @@ public function dumpStructure($tableInfo, $picoTableName, $createIfNotExists = f $autoIncrementKeys = $this->getAutoIncrementKey($tableInfo); - $query[] = "$createStatement `$picoTableName` ("; + $query[] = "$createStatement `$tableName` ("; foreach($tableInfo->getColumns() as $column) { @@ -106,7 +106,7 @@ public function dumpStructure($tableInfo, $picoTableName, $createIfNotExists = f if(isset($pk) && is_array($pk) && !empty($pk)) { $query[] = ""; - $query[] = "ALTER TABLE `$picoTableName`"; + $query[] = "ALTER TABLE `$tableName`"; foreach($pk as $primaryKey) { $query[] = "\tADD PRIMARY KEY (`$primaryKey[name]`)"; @@ -119,7 +119,7 @@ public function dumpStructure($tableInfo, $picoTableName, $createIfNotExists = f if(isset($autoIncrementKeys) && is_array($autoIncrementKeys) && in_array($column[parent::KEY_NAME], $autoIncrementKeys)) { $query[] = ""; - $query[] = "ALTER TABLE `$picoTableName` \r\n\tMODIFY ".trim($this->createColumn($column), " \r\n\t ")." AUTO_INCREMENT"; + $query[] = "ALTER TABLE `$tableName` \r\n\tMODIFY ".trim($this->createColumn($column), " \r\n\t ")." AUTO_INCREMENT"; $query[] = ";"; } } @@ -199,13 +199,13 @@ public function fixDefaultValue($defaultValue, $type) * columns based on the provided column definitions. * * @param array $columns An associative array where keys are column names and values are column details. - * @param string $picoTableName The name of the table where the record will be inserted. + * @param string $tableName The name of the table where the record will be inserted. * @param MagicObject $record The data record to be inserted, which provides a method to retrieve values. * * @return string The generated SQL INSERT statement. * @throws Exception If the record cannot be processed or if there are no values to insert. */ - public function dumpRecord($columns, $picoTableName, $record) + public function dumpRecord($columns, $tableName, $record) { $value = $record->valueArray(); $rec = array(); @@ -219,7 +219,7 @@ public function dumpRecord($columns, $picoTableName, $record) $queryBuilder = new PicoDatabaseQueryBuilder(PicoDatabaseType::DATABASE_TYPE_MYSQL); $queryBuilder->newQuery() ->insert() - ->into($picoTableName) + ->into($tableName) ->fields(array_keys($rec)) ->values(array_values($rec)); diff --git a/src/Util/Database/PicoDatabaseUtilPostgreSql.php b/src/Util/Database/PicoDatabaseUtilPostgreSql.php index e282fa6..0db1fb1 100644 --- a/src/Util/Database/PicoDatabaseUtilPostgreSql.php +++ b/src/Util/Database/PicoDatabaseUtilPostgreSql.php @@ -54,13 +54,13 @@ class PicoDatabaseUtilPostgreSql extends PicoDatabaseUtilBase implements PicoDat * and default values. * * @param PicoDatabase $database The database connection instance. - * @param string $picoTableName The name of the table to retrieve column information from. + * @param string $tableName The name of the table to retrieve column information from. * @return array An array of associative arrays containing details about each column, * where each associative array includes 'column_name', 'data_type', * 'is_nullable', and 'column_default'. * @throws Exception If the database connection fails or the query cannot be executed. */ - public function getColumnList($database, $picoTableName) + public function getColumnList($database, $tableName) { $schema = $database->getDatabaseCredentials()->getDatabaseSchema(); if(!isset($schema) || empty($schema)) @@ -69,7 +69,7 @@ public function getColumnList($database, $picoTableName) } $sql = "SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns - WHERE table_schema = '$schema' AND table_name = '$picoTableName'"; + WHERE table_schema = '$schema' AND table_name = '$tableName'"; return $database->fetchAll($sql); } @@ -81,18 +81,18 @@ public function getColumnList($database, $picoTableName) * "DROP TABLE IF EXISTS". It also handles the definition of primary keys if present. * * @param PicoTableInfo $tableInfo The information about the table, including column details and primary keys. - * @param string $picoTableName The name of the table for which the structure is being generated. + * @param string $tableName The name of the table for which the structure is being generated. * @param bool $createIfNotExists Whether to add "IF NOT EXISTS" in the CREATE statement (default is false). * @param bool $dropIfExists Whether to add "DROP TABLE IF EXISTS" before the CREATE statement (default is false). * @param string|null $engine The storage engine to use for the table (optional, default is null). * @param string|null $charset The character set to use for the table (optional, default is null). * @return string The SQL statement to create the table, including column definitions and primary keys. */ - public function dumpStructure($tableInfo, $picoTableName, $createIfNotExists = false, $dropIfExists = false, $engine = null, $charset = null) + public function dumpStructure($tableInfo, $tableName, $createIfNotExists = false, $dropIfExists = false, $engine = null, $charset = null) { $query = []; if ($dropIfExists) { - $query[] = "-- DROP TABLE IF EXISTS \"$picoTableName\";"; + $query[] = "-- DROP TABLE IF EXISTS \"$tableName\";"; $query[] = ""; } @@ -103,7 +103,7 @@ public function dumpStructure($tableInfo, $picoTableName, $createIfNotExists = f $autoIncrementKeys = $this->getAutoIncrementKey($tableInfo); - $query[] = "$createStatement \"$picoTableName\" ("; + $query[] = "$createStatement \"$tableName\" ("; foreach ($tableInfo->getColumns() as $column) { $query[] = $this->createColumn($column); @@ -114,7 +114,7 @@ public function dumpStructure($tableInfo, $picoTableName, $createIfNotExists = f $pk = $tableInfo->getPrimaryKeys(); if (isset($pk) && is_array($pk) && !empty($pk)) { $query[] = ""; - $query[] = "ALTER TABLE \"$picoTableName\""; + $query[] = "ALTER TABLE \"$tableName\""; foreach ($pk as $primaryKey) { $query[] = "\tADD PRIMARY KEY (\"$primaryKey[name]\")"; } @@ -195,13 +195,13 @@ public function fixDefaultValue($defaultValue, $type) * columns based on the provided column definitions. * * @param array $columns An associative array where keys are column names and values are column details. - * @param string $picoTableName The name of the table where the record will be inserted. + * @param string $tableName The name of the table where the record will be inserted. * @param MagicObject $record The data record to be inserted, which provides a method to retrieve values. * * @return string The generated SQL INSERT statement. * @throws Exception If the record cannot be processed or if there are no values to insert. */ - public function dumpRecord($columns, $picoTableName, $record) + public function dumpRecord($columns, $tableName, $record) { $value = $record->valueArray(); $rec = []; @@ -214,7 +214,7 @@ public function dumpRecord($columns, $picoTableName, $record) $queryBuilder = new PicoDatabaseQueryBuilder(PicoDatabaseType::DATABASE_TYPE_POSTGRESQL); $queryBuilder->newQuery() ->insert() - ->into($picoTableName) + ->into($tableName) ->fields(array_keys($rec)) ->values(array_values($rec)); diff --git a/src/Util/Database/PicoDatabaseUtilSqlite.php b/src/Util/Database/PicoDatabaseUtilSqlite.php new file mode 100644 index 0000000..9d25b95 --- /dev/null +++ b/src/Util/Database/PicoDatabaseUtilSqlite.php @@ -0,0 +1,423 @@ +tableInfo(); + $tableName = $tableInfo->getTableName(); + + // Start building the CREATE TABLE query + if($createIfNotExists) + { + $condition = " IF NOT EXISTS"; + } + else + { + $condition = ""; + } + + $autoIncrementKeys = $this->getAutoIncrementKey($tableInfo); + + $query = ""; + if($dropIfExists) + { + $query .= "-- DROP TABLE IF EXISTS `$tableName`;\r\n\r\n"; + } + $query .= "CREATE TABLE$condition $tableName (\n"; + + // Define primary key + $primaryKey = null; + + $pKeys = $tableInfo->getPrimaryKeys(); + + $pKeyArr = []; + $pKeyArrUsed = []; + if(isset($pKeys) && is_array($pKeys) && !empty($pKeys)) + { + $pkVals = array_values($pKeys); + foreach($pkVals as $pk) + { + $pKeyArr[] = $pk['name']; + } + } + + foreach ($tableInfo->getColumns() as $column) { + + $columnName = $column['name']; + $columnType = $column['type']; + $length = isset($column['length']) ? $column['length'] : null; + $nullable = (isset($column['nullable']) && $column['nullable'] === 'true') ? ' NULL' : ' NOT NULL'; + $defaultValue = isset($column['default_value']) ? " DEFAULT '{$column['default_value']}'" : ''; + + // Convert column type for SQL + $columnType = strtolower($columnType); // Convert to lowercase for case-insensitive comparison + + if(isset($autoIncrementKeys) && is_array($autoIncrementKeys) && in_array($column[parent::KEY_NAME], $autoIncrementKeys)) { + $sqlType = 'INTEGER PRIMARY KEY AUTOINCREMENT'; + $pKeyArrUsed[] = $columnName; + } elseif (strpos($columnType, 'varchar') !== false) { + $sqlType = "VARCHAR($length)"; + } elseif ($columnType === 'int') { + $sqlType = 'INT'; + } elseif ($columnType === 'float') { + $sqlType = 'FLOAT'; + } elseif ($columnType === 'text') { + $sqlType = 'TEXT'; + } elseif ($columnType === 'longtext') { + $sqlType = 'LONGTEXT'; + } elseif ($columnType === 'date') { + $sqlType = 'DATE'; + } elseif ($columnType === 'timestamp') { + $sqlType = 'TIMESTAMP'; + } elseif ($columnType === 'tinyint(1)') { + $sqlType = 'TINYINT(1)'; + } else { + $sqlType = 'VARCHAR(255)'; // Fallback type + } + + // Add to query + $query .= " $columnName $sqlType$nullable$defaultValue,\n"; + + } + + // Remove the last comma and add primary key constraint + $query = rtrim($query, ",\n") . "\n"; + + $pKeyArrFinal = []; + foreach($pKeyArr as $k=>$v) + { + if(!in_array($v, $pKeyArrUsed)) + { + $pKeyArrFinal[] = $v; + } + } + + if (!empty($pKeyArrFinal)) { + $primaryKey = implode(", ", $pKeyArrFinal); + $query = rtrim($query, ",\n"); + $query .= ",\n PRIMARY KEY ($primaryKey)\n"; + } + + $query .= ");"; + + return str_replace("\n", "\r\n", $query); + } + + /** + * Retrieves a list of columns for a specified table in the database. + * + * This method queries the information schema to obtain details about the columns + * of the specified table, including their names, data types, nullability, + * default values, and any additional attributes such as primary keys and auto-increment. + * + * @param PicoDatabase $database The database connection instance. + * @param string $tableName The name of the table to retrieve column information from. + * @return array An array of associative arrays containing details about each column, + * where each associative array includes: + * - 'Field': The name of the column. + * - 'Type': The data type of the column. + * - 'Null': Indicates if the column allows NULL values ('YES' or 'NO'). + * - 'Key': Indicates if the column is a primary key ('PRI' or null). + * - 'Default': The default value of the column, or 'None' if not set. + * - 'Extra': Additional attributes of the column, such as 'auto_increment'. + * @throws Exception If the database connection fails or the query cannot be executed. + */ + public function getColumnList($database, $tableName) + { + $stmt = $database->query("PRAGMA table_info($tableName)"); + + // Fetch and display the column details + $rows = array(); + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + $rows[] = array( + "Field" => $row['name'], + "Type" => $row['type'], + "Null" => $row['notnull'] ? 'YES' : 'NO', + "Key" => $row['pk'] ? 'PRI' : null, + "Default" => $row['dflt_value'] ? $row['dflt_value'] : 'None', + "Extra" => ($row['pk'] == 1 && $row['type'] === 'INTEGER') ? 'auto_increment' : null + ); + } + return $rows; + } + + /** + * Dumps the structure of a table as a SQL statement. + * + * This method generates a SQL CREATE TABLE statement based on the provided table information, + * including the option to include or exclude specific clauses such as "IF NOT EXISTS" and + * "DROP TABLE IF EXISTS". It also handles the definition of primary keys if present. + * + * @param PicoTableInfo $tableInfo The information about the table, including column details and primary keys. + * @param string $tableName The name of the table for which the structure is being generated. + * @param bool $createIfNotExists Whether to add "IF NOT EXISTS" in the CREATE statement (default is false). + * @param bool $dropIfExists Whether to add "DROP TABLE IF EXISTS" before the CREATE statement (default is false). + * @param string|null $engine The storage engine to use for the table (optional, default is null). + * @param string|null $charset The character set to use for the table (optional, default is null). + * @return string The SQL statement to create the table, including column definitions and primary keys. + */ + public function dumpStructure($tableInfo, $tableName, $createIfNotExists = false, $dropIfExists = false, $engine = 'InnoDB', $charset = 'utf8mb4') + { + $query = array(); + $columns = array(); + if($dropIfExists) + { + $query[] = "-- DROP TABLE IF EXISTS `$tableName`;"; + $query[] = ""; + } + $createStatement = ""; + + $createStatement = "CREATE TABLE"; + if($createIfNotExists) + { + $createStatement .= " IF NOT EXISTS"; + } + + $autoIncrementKeys = $this->getAutoIncrementKey($tableInfo); + + $query[] = "$createStatement `$tableName` ("; + + foreach($tableInfo->getColumns() as $column) + { + $columns[] = $this->createColumn($column); + } + $query[] = implode(",\r\n", $columns); + $query[] = ") ENGINE=$engine DEFAULT CHARSET=$charset;"; + + $pk = $tableInfo->getPrimaryKeys(); + if(isset($pk) && is_array($pk) && !empty($pk)) + { + $query[] = ""; + $query[] = "ALTER TABLE `$tableName`"; + foreach($pk as $primaryKey) + { + $query[] = "\tADD PRIMARY KEY (`$primaryKey[name]`)"; + } + $query[] = ";"; + } + + foreach($tableInfo->getColumns() as $column) + { + if(isset($autoIncrementKeys) && is_array($autoIncrementKeys) && in_array($column[parent::KEY_NAME], $autoIncrementKeys)) + { + $query[] = ""; + $query[] = "ALTER TABLE `$tableName` \r\n\tMODIFY ".trim($this->createColumn($column), " \r\n\t ")." AUTO_INCREMENT"; + $query[] = ";"; + } + } + + return implode("\r\n", $query); + } + + /** + * Creates a column definition for a SQL statement. + * + * This method constructs a SQL column definition based on the provided column details, + * including the column name, data type, nullability, and default value. The resulting + * definition is formatted for use in a CREATE TABLE statement. + * + * @param array $column An associative array containing details about the column: + * - string name: The name of the column. + * - string type: The data type of the column (e.g., VARCHAR, INT). + * - bool|string nullable: Indicates if the column allows NULL values (true or 'true' for NULL; otherwise, NOT NULL). + * - mixed default_value: The default value for the column (optional). + * + * @return string The SQL column definition formatted as a string, suitable for inclusion in a CREATE TABLE statement. + */ + public function createColumn($column) + { + $col = array(); + $col[] = "\t"; + $col[] = "`".$column[parent::KEY_NAME]."`"; + $col[] = $column['type']; + if(isset($column['nullable']) && strtolower(trim($column['nullable'])) == 'true') + { + $col[] = "NULL"; + } + else + { + $col[] = "NOT NULL"; + } + if(isset($column['default_value'])) + { + $defaultValue = $column['default_value']; + $defaultValue = $this->fixDefaultValue($defaultValue, $column['type']); + $col[] = "DEFAULT $defaultValue"; + } + return implode(" ", $col); + } + + /** + * Fixes the default value for SQL insertion based on its type. + * + * This method processes the given default value according to the specified data type, + * ensuring that it is correctly formatted for SQL insertion. For string-like types, + * the value is enclosed in single quotes, while boolean and null values are returned + * as is. + * + * @param mixed $defaultValue The default value to fix, which can be a string, boolean, or null. + * @param string $type The data type of the column (e.g., ENUM, CHAR, TEXT, INT, FLOAT, DOUBLE). + * + * @return mixed The fixed default value formatted appropriately for SQL insertion. + */ + public function fixDefaultValue($defaultValue, $type) + { + if(strtolower($defaultValue) == 'true' || strtolower($defaultValue) == 'false' || strtolower($defaultValue) == 'null') + { + return $defaultValue; + } + if(stripos($type, 'enum') !== false || stripos($type, 'char') !== false || stripos($type, 'text') !== false || stripos($type, 'int') !== false || stripos($type, 'float') !== false || stripos($type, 'double') !== false) + { + return "'".$defaultValue."'"; + } + return $defaultValue; + } + + /** + * Fixes imported data based on specified column types. + * + * This method processes the input data array and adjusts the values + * according to the expected types defined in the columns array. It + * supports boolean, integer, and float types. + * + * @param mixed[] $data The input data to be processed. + * @param string[] $columns An associative array mapping column names to their types. + * @return mixed[] The updated data array with fixed types. + */ + public function fixImportData($data, $columns) + { + // Iterate through each item in the data array + foreach($data as $name=>$value) + { + // Check if the column exists in the columns array + if(isset($columns[$name])) + { + $type = $columns[$name]; + + if(strtolower($type) == 'tinyint(1)' || strtolower($type) == 'boolean' || strtolower($type) == 'bool') + { + // Process boolean types + $data = $this->fixBooleanData($data, $name, $value); + } + else if(stripos($type, 'integer') !== false || stripos($type, 'int(') !== false) + { + // Process integer types + $data = $this->fixIntegerData($data, $name, $value); + } + else if(stripos($type, 'float') !== false || stripos($type, 'double') !== false || stripos($type, 'decimal') !== false) + { + // Process float types + $data = $this->fixFloatData($data, $name, $value); + } + } + } + return $data; + } + + /** + * Automatically configures the import data settings based on the source and target databases. + * + * This method connects to the source and target databases, retrieves the list of existing + * tables, and updates the configuration for each target table by checking its presence in the + * source database. It handles exceptions and logs any errors encountered during the process. + * + * @param SecretObject $config The configuration object containing database and table information. + * @return SecretObject The updated configuration object with modified table settings. + */ + public function autoConfigureImportData($config) + { + $databaseConfigSource = $config->getDatabaseSource(); + $databaseConfigTarget = $config->getDatabaseTarget(); + + $databaseSource = new PicoDatabase($databaseConfigSource); + $databaseTarget = new PicoDatabase($databaseConfigTarget); + try + { + $databaseSource->connect(); + $databaseTarget->connect(); + $tables = $config->getTable(); + + $existingTables = array(); + foreach($tables as $tb) + { + $existingTables[] = $tb->getTarget(); + } + + $sourceTableList = $databaseSource->fetchAll("SELECT name FROM sqlite_master WHERE type='table'", PDO::FETCH_NUM); + $targetTableList = $databaseTarget->fetchAll("SELECT name FROM sqlite_master WHERE type='table'", PDO::FETCH_NUM); + + $sourceTables = call_user_func_array('array_merge', $sourceTableList); + $targetTables = call_user_func_array('array_merge', $targetTableList); + + foreach($targetTables as $target) + { + $tables = $this->updateConfigTable($databaseSource, $databaseTarget, $tables, $sourceTables, $target, $existingTables); + } + $config->setTable($tables); + } + catch(Exception $e) + { + error_log($e->getMessage()); + } + return $config; + } + +} \ No newline at end of file diff --git a/tests/sqlite.php b/tests/sqlite.php index ad2287c..b39f8c1 100644 --- a/tests/sqlite.php +++ b/tests/sqlite.php @@ -2,6 +2,7 @@ use MagicObject\Database\PicoSqlite; use MagicObject\MagicObject; +use MagicObject\Util\Database\PicoDatabaseUtilSqlite; require_once dirname(__DIR__) . "/vendor/autoload.php"; @@ -181,6 +182,69 @@ class Album extends MagicObject } +/** + * AcuanPengawasan is entity of table acuan_pengawasan. You can join this entity to other entity using annotation JoinColumn. + * Don't forget to add "use" statement if the entity is outside the namespace. + * @link https://github.com/Planetbiru/MagicObject/blob/main/tutorial.md#entity + * + * @package Sipro\Entity\Data + * @Entity + * @JSON(property-naming-strategy=SNAKE_CASE, prettify=false) + * @Table(name="acuan_pengawasan") + */ +class AcuanPengawasan extends MagicObject +{ + /** + * Acuan Pengawasan ID + * + * @Id + * @GeneratedValue(strategy=GenerationType.IDENTITY) + * @NotNull + * @Column(name="acuan_pengawasan_id", type="bigint(20)", length=20, nullable=false, extra="auto_increment") + * @Label(content="Acuan Pengawasan ID") + * @var integer + */ + protected $acuanPengawasanId; + + /** + * Nama + * + * @Column(name="nama", type="varchar(100)", length=100, nullable=true) + * @Label(content="Nama") + * @var string + */ + protected $nama; + + /** + * Sort Order + * + * @Column(name="sort_order", type="int(11)", length=11, nullable=true) + * @Label(content="Sort Order") + * @var integer + */ + protected $sortOrder; + + /** + * Default Data + * + * @Column(name="default_data", type="tinyint(1)", length=1, nullable=true) + * @Label(content="Default Data") + * @var boolean + */ + protected $defaultData; + + /** + * Aktif + * + * @Column(name="aktif", type="tinyint(1)", length=1, default_value="1", nullable=true) + * @DefaultColumn(value="1") + * @Label(content="Aktif") + * @var boolean + */ + protected $aktif; + +} + $database = new PicoSqlite(__DIR__ . "/db.sqlite", null, function($sql){ //echo $sql."\r\n"; }); @@ -189,12 +253,24 @@ class Album extends MagicObject $database->connect(); $album = new Album(null, $database); + $acuanPengawasan = new AcuanPengawasan(null, $database); // create table if not exists - $tableStructure = $database->showCreateTable($album, true); + $util = new PicoDatabaseUtilSqlite(); + $tableStructure = $util->showCreateTable($album, true); + echo $tableStructure; + print_r($util->getColumnList($database, 'album')); $database->query($tableStructure); + $tableStructure2 = $util->showCreateTable($acuanPengawasan, true); + echo $tableStructure2; + + print_r($util->getColumnList($database, 'acuan_pengawasan')); + $database->query($tableStructure); + $database->query($tableStructure2); + + $album->setAlbumId("1235"); $album->setName("Meraih Mimpi 2 "); $album->setTitle("Meraih Mimpi 2"); diff --git a/tutorial.md b/tutorial.md index 22150bc..44cc2b0 100644 --- a/tutorial.md +++ b/tutorial.md @@ -11609,6 +11609,7 @@ $sqlite->delete('users', $conditions); use MagicObject\Database\PicoSqlite; use MagicObject\MagicObject; +use MagicObject\Util\Database\PicoDatabaseUtilSqlite; require_once dirname(__DIR__) . "/vendor/autoload.php"; @@ -11798,8 +11799,8 @@ try $album = new Album(null, $database); // create table if not exists - $tableStructure = $database->showCreateTable($album, true); - + $util = new PicoDatabaseUtilSqlite(); + $tableStructure = $util->showCreateTable($album, true); $database->query($tableStructure); $album->setAlbumId("1235");