]> git.mxchange.org Git - friendica.git/commitdiff
DBStructure enhancements (#5437)
authorPhilipp <admin+Github@philipp.info>
Sat, 21 Jul 2018 12:43:43 +0000 (14:43 +0200)
committerHypolite Petovan <mrpetovan@eml.cc>
Sat, 21 Jul 2018 12:43:43 +0000 (08:43 -0400)
* Adding DBStructure enhancements

- Added DBStructure::rename()
- Added DBStructure::existTable()
- Added DBStructure::existColumn()

(cherry picked from commit 4ae06ec)

* Adding `pre_update_1279` method

- Added DBStructure::rename()
- Added DBStructure::existTable()
- Added DBStructure::existColumn()

(cherry picked from commit 8496d84)

* code standards

(cherry picked from commit 551d09b)

* simplify to `empty` instead `is_null`

(cherry picked from commit ce68835)

src/Database/DBA.php
src/Database/DBStructure.php
tests/src/Core/Lock/LockTest.php
tests/src/Database/DBATest.php [new file with mode: 0644]
tests/src/Database/DBStructureTest.php [new file with mode: 0644]

index 4027f56d4e1bc5c5aec2ff6b1d8bae2a82543bd3..51b2c8898e6b49524d6d0000c6d146ad17aa6092 100644 (file)
@@ -644,6 +644,10 @@ class DBA
 
                $fields = [];
 
+               if (empty($condition)) {
+                       return DBStructure::existsTable($table);
+               }
+
                reset($condition);
                $first_key = key($condition);
                if (!is_int($first_key)) {
index 55188d2b39c19a42e3666721d2e4d0f6caf04221..c6c8c156626012b2e2844888567ce6cf8c4cb8d7 100644 (file)
@@ -684,6 +684,141 @@ class DBStructure
                return $sql;
        }
 
+       /**
+        *      Check if a table exists
+        *
+        * @param string $table Table name
+        *
+        * @return boolean Does the table exist?
+        */
+       public static function existsTable($table)
+       {
+               if (empty($table)) {
+                       return false;
+               }
+
+               $table = DBA::escape($table);
+
+               $sql = "SHOW TABLES LIKE '" . $table . "';";
+
+               $stmt = DBA::p($sql);
+
+               if (is_bool($stmt)) {
+                       $retval = $stmt;
+               } else {
+                       $retval = (DBA::num_rows($stmt) > 0);
+               }
+
+               DBA::close($stmt);
+
+               return $retval;
+       }
+
+       /**
+        *      Check if the columns of the table exists
+        *
+        * @param string $table   Table name
+        * @param array  $columns Columns to check ( Syntax: [ $col1, $col2, .. ] )
+        *
+        * @return boolean Does the table exist?
+        */
+       public static function existsColumn($table, $columns = []) {
+               if (empty($table)) {
+                       return false;
+               }
+
+               if (is_null($columns) || empty($columns)) {
+                       return self::existsTable($table);
+               }
+
+               $table = DBA::escape($table);
+
+               foreach ($columns AS $column) {
+                       $sql = "SHOW COLUMNS FROM `" . $table . "` LIKE '" . $column . "';";
+
+                       $stmt = DBA::p($sql);
+
+                       if (is_bool($stmt)) {
+                               $retval = $stmt;
+                       } else {
+                               $retval = (DBA::num_rows($stmt) > 0);
+                       }
+
+                       DBA::close($stmt);
+
+                       if (!$retval) {
+                               return false;
+                       }
+               }
+
+               return true;
+       }
+
+       const RENAME_COLUMN = 0;
+       const RENAME_PRIMARY_KEY = 1;
+
+       /**
+        * Renames columns or the primary key of a table
+        * @todo You cannot rename a primary key if "auto increment" is set
+        *
+        * @param string $table    Table name
+        * @param array  $columns  Columns Syntax for Rename: [ $old1 => [ $new1, $type1 ], $old2 => [ $new2, $type2 ], ... ] )
+        *                                 Syntax for Primary Key: [ $col1, $col2, ...] )
+        * @param int    $type     The type of renaming (Default is Column)
+        *
+        * @return boolean Was the renaming successful?
+        *
+        */
+       public static function rename($table, $columns, $type = self::RENAME_COLUMN) {
+               if (empty($table) || empty($columns)) {
+                       return false;
+               }
+
+               if (!is_array($columns)) {
+                       return false;
+               }
+
+               $table = DBA::escape($table);
+
+               $sql = "ALTER TABLE `" . $table . "`";
+               switch ($type) {
+                       case self::RENAME_COLUMN:
+                               if (!self::existsColumn($table, array_keys($columns))) {
+                                       return false;
+                               }
+                               $sql .= implode(',', array_map(
+                                       function ($to, $from) {
+                                               return " CHANGE `" . $from . "` `" . $to[0] . "` " . $to[1];
+                                       },
+                                       $columns,
+                                       array_keys($columns)
+                               ));
+                               break;
+                       case self::RENAME_PRIMARY_KEY:
+                               if (!self::existsColumn($table, $columns)) {
+                                       return false;
+                               }
+                               $sql .= " DROP PRIMARY KEY, ADD PRIMARY KEY(`" . implode('`, `', $columns) . "`)";
+                               break;
+                       default:
+                               return false;
+               }
+
+               $sql .= ";";
+
+               $stmt = DBA::p($sql);
+
+               if (is_bool($stmt)) {
+                       $retval = $stmt;
+               } else {
+                       $retval = true;
+               }
+
+               DBA::close($stmt);
+
+               return $retval;
+       }
+
        public static function definition() {
                $database = [];
 
index 5663a26af1a9d5c6cb00fc68003a2e7ad1c5b695..9698f0bdea42ef587a0692e5989db16c7b927c1b 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace Friendica\Test\src\Core\Lock;
 
+use Friendica\BaseObject;
 use Friendica\Core\Config;
 use Friendica\Test\DatabaseTest;
 
@@ -20,7 +21,7 @@ abstract class LockTest extends DatabaseTest
                $this->instance = $this->getInstance();
 
                // Reusable App object
-               $this->app = \Friendica\BaseObject::getApp();
+               $this->app = BaseObject::getApp();
 
                // Default config
                Config::set('config', 'hostname', 'localhost');
diff --git a/tests/src/Database/DBATest.php b/tests/src/Database/DBATest.php
new file mode 100644 (file)
index 0000000..17ac55f
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+namespace Friendica\Test\Database;
+
+use Friendica\BaseObject;
+use Friendica\Core\Config;
+use Friendica\Database\DBA;
+use Friendica\Test\DatabaseTest;
+
+class DBATest extends DatabaseTest
+{
+       public function setUp()
+       {
+               parent::setUp();
+
+               // Reusable App object
+               $this->app = BaseObject::getApp();
+
+               // Default config
+               Config::set('config', 'hostname', 'localhost');
+               Config::set('system', 'throttle_limit_day', 100);
+               Config::set('system', 'throttle_limit_week', 100);
+               Config::set('system', 'throttle_limit_month', 100);
+               Config::set('system', 'theme', 'system_theme');
+       }
+
+       /**
+        * @small
+        */
+       public function testExists() {
+
+               $this->assertTrue(DBA::exists('config', []));
+               $this->assertFalse(DBA::exists('notable', []));
+
+               $this->assertTrue(DBA::exists('config', null));
+               $this->assertFalse(DBA::exists('notable', null));
+
+               $this->assertTrue(DBA::exists('config', ['k' => 'hostname']));
+               $this->assertFalse(DBA::exists('config', ['k' => 'nonsense']));
+       }
+}
diff --git a/tests/src/Database/DBStructureTest.php b/tests/src/Database/DBStructureTest.php
new file mode 100644 (file)
index 0000000..268bf8e
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+namespace Friendica\Test\Database;
+
+use Friendica\BaseObject;
+use Friendica\Core\Config;
+use Friendica\Database\DBStructure;
+use Friendica\Test\DatabaseTest;
+
+class DBStructureTest extends DatabaseTest
+{
+       public function setUp()
+       {
+               parent::setUp();
+
+               // Reusable App object
+               $this->app = BaseObject::getApp();
+
+               // Default config
+               Config::set('config', 'hostname', 'localhost');
+               Config::set('system', 'throttle_limit_day', 100);
+               Config::set('system', 'throttle_limit_week', 100);
+               Config::set('system', 'throttle_limit_month', 100);
+               Config::set('system', 'theme', 'system_theme');
+       }
+
+       /**
+        * @small
+        */
+       public function testExists() {
+               $this->assertTrue(DBStructure::existsTable('config'));
+
+               $this->assertFalse(DBStructure::existsTable('notatable'));
+
+               $this->assertTrue(DBStructure::existsColumn('config', ['k']));
+               $this->assertFalse(DBStructure::existsColumn('config', ['nonsense']));
+               $this->assertFalse(DBStructure::existsColumn('config', ['k', 'nonsense']));
+       }
+
+       /**
+        * @small
+        */
+       public function testRename() {
+               $fromColumn = 'k';
+               $toColumn = 'key';
+               $fromType = 'varbinary(255) not null';
+               $toType = 'varbinary(255) not null comment \'Test To Type\'';
+
+               $this->assertTrue(DBStructure::rename('config', [ $fromColumn => [ $toColumn, $toType ]]));
+               $this->assertTrue(DBStructure::existsColumn('config', [ $toColumn ]));
+               $this->assertFalse(DBStructure::existsColumn('config', [ $fromColumn ]));
+
+               $this->assertTrue(DBStructure::rename('config', [ $toColumn => [ $fromColumn, $fromType ]]));
+               $this->assertTrue(DBStructure::existsColumn('config', [ $fromColumn ]));
+               $this->assertFalse(DBStructure::existsColumn('config', [ $toColumn ]));
+       }
+
+       /**
+        * @small
+        */
+       public function testChangePrimaryKey() {
+               $oldID = 'client_id';
+               $newID = 'pw';
+
+               $this->assertTrue(DBStructure::rename('clients', [ $newID ], DBStructure::RENAME_PRIMARY_KEY));
+               $this->assertTrue(DBStructure::rename('clients', [ $oldID ], DBStructure::RENAME_PRIMARY_KEY));
+       }
+}