Browse Source

Add COLUMN_TYPE MySQL reflection

Maurits van der Schee 5 years ago
parent
commit
a94c4f61b7

+ 51
- 8
api.php View File

@@ -3560,13 +3560,54 @@ namespace Tqdev\PhpCrudApi\Column\Reflection {
3560 3560
             $this->sanitize();
3561 3561
         }
3562 3562
 
3563
+        private static function parseColumnType(string $columnType, int &$length, int &$precision, int &$scale) /*: void*/
3564
+        {
3565
+            $pos = strpos($columnType, '(');
3566
+            if ($pos) {
3567
+                $dataSize = rtrim(substr($columnType, $pos + 1), ')');
3568
+                if ($length) {
3569
+                    $length = (int) $dataSize;
3570
+                } else {
3571
+                    $pos = strpos($dataSize, ',');
3572
+                    if ($pos) {
3573
+                        $precision = (int) substr($dataSize, 0, $pos);
3574
+                        $scale = (int) substr($dataSize, $pos + 1);
3575
+                    } else {
3576
+                        $precision = (int) $dataSize;
3577
+                        $scale = 0;
3578
+                    }
3579
+                }
3580
+            }
3581
+        }
3582
+
3583
+        private static function getDataSize(int $length, int $precision, int $scale): string
3584
+        {
3585
+            $dataSize = '';
3586
+            if ($length) {
3587
+                $dataSize = $length;
3588
+            } elseif ($precision) {
3589
+                if ($scale) {
3590
+                    $dataSize = $precision . ',' . $scale;
3591
+                } else {
3592
+                    $dataSize = $precision;
3593
+                }
3594
+            }
3595
+            return $dataSize;
3596
+        }
3597
+
3563 3598
         public static function fromReflection(GenericReflection $reflection, array $columnResult): ReflectedColumn
3564 3599
         {
3565 3600
             $name = $columnResult['COLUMN_NAME'];
3601
+            $dataType = $columnResult['DATA_TYPE'];
3566 3602
             $length = (int) $columnResult['CHARACTER_MAXIMUM_LENGTH'];
3567
-            $type = $reflection->toJdbcType($columnResult['DATA_TYPE'], $length);
3568 3603
             $precision = (int) $columnResult['NUMERIC_PRECISION'];
3569 3604
             $scale = (int) $columnResult['NUMERIC_SCALE'];
3605
+            $columnType = $columnResult['COLUMN_TYPE'];
3606
+            if ($columnType) {
3607
+                self::parseColumnType($columnType, $length, $precision, $scale);
3608
+            }
3609
+            $dataSize = self::getDataSize($length, $precision, $scale);
3610
+            $type = $reflection->toJdbcType($dataType, $dataSize);
3570 3611
             $nullable = in_array(strtoupper($columnResult['IS_NULLABLE']), ['TRUE', 'YES', 'T', 'Y', '1']);
3571 3612
             $pk = false;
3572 3613
             $fk = '';
@@ -4107,9 +4148,10 @@ namespace Tqdev\PhpCrudApi\Column {
4107 4148
 
4108 4149
         private function database(): ReflectedDatabase
4109 4150
         {
4110
-            if (!$this->database) {
4111
-                $this->database = $this->loadDatabase(true);
4151
+            if ($this->database) {
4152
+                return $this->database;
4112 4153
             }
4154
+            $this->database = $this->loadDatabase(true);
4113 4155
             return $this->database;
4114 4156
         }
4115 4157
 
@@ -5961,11 +6003,11 @@ namespace Tqdev\PhpCrudApi\Database {
5961 6003
         {
5962 6004
             switch ($this->driver) {
5963 6005
                 case 'mysql':
5964
-                    return 'SELECT "COLUMN_NAME", "IS_NULLABLE", "DATA_TYPE", if ("DATA_TYPE"=\'tinyint\' OR "DATA_TYPE"=\'bit\',SUBSTRING_INDEX(SUBSTRING_INDEX("COLUMN_TYPE",\'(\',-1),\')\',1),"CHARACTER_MAXIMUM_LENGTH") as "CHARACTER_MAXIMUM_LENGTH", "NUMERIC_PRECISION", "NUMERIC_SCALE" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "TABLE_SCHEMA" = ?';
6006
+                    return 'SELECT "COLUMN_NAME", "IS_NULLABLE", "DATA_TYPE", "CHARACTER_MAXIMUM_LENGTH" as "CHARACTER_MAXIMUM_LENGTH", "NUMERIC_PRECISION", "NUMERIC_SCALE", "COLUMN_TYPE" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "TABLE_SCHEMA" = ?';
5965 6007
                 case 'pgsql':
5966
-                    return 'SELECT a.attname AS "COLUMN_NAME", case when a.attnotnull then \'NO\' else \'YES\' end as "IS_NULLABLE", pg_catalog.format_type(a.atttypid, -1) as "DATA_TYPE", case when a.atttypmod < 0 then NULL else a.atttypmod-4 end as "CHARACTER_MAXIMUM_LENGTH", case when a.atttypid != 1700 then NULL else ((a.atttypmod - 4) >> 16) & 65535 end as "NUMERIC_PRECISION", case when a.atttypid != 1700 then NULL else (a.atttypmod - 4) & 65535 end as "NUMERIC_SCALE" FROM pg_attribute a JOIN pg_class pgc ON pgc.oid = a.attrelid WHERE pgc.relname = ? AND \'\' <> ? AND a.attnum > 0 AND NOT a.attisdropped;';
6008
+                    return 'SELECT a.attname AS "COLUMN_NAME", case when a.attnotnull then \'NO\' else \'YES\' end as "IS_NULLABLE", pg_catalog.format_type(a.atttypid, -1) as "DATA_TYPE", case when a.atttypmod < 0 then NULL else a.atttypmod-4 end as "CHARACTER_MAXIMUM_LENGTH", case when a.atttypid != 1700 then NULL else ((a.atttypmod - 4) >> 16) & 65535 end as "NUMERIC_PRECISION", case when a.atttypid != 1700 then NULL else (a.atttypmod - 4) & 65535 end as "NUMERIC_SCALE", \'\' AS "COLUMN_TYPE" FROM pg_attribute a JOIN pg_class pgc ON pgc.oid = a.attrelid WHERE pgc.relname = ? AND \'\' <> ? AND a.attnum > 0 AND NOT a.attisdropped;';
5967 6009
                 case 'sqlsrv':
5968
-                    return 'SELECT c.name AS "COLUMN_NAME", c.is_nullable AS "IS_NULLABLE", t.Name AS "DATA_TYPE", (c.max_length/2) AS "CHARACTER_MAXIMUM_LENGTH", c.precision AS "NUMERIC_PRECISION", c.scale AS "NUMERIC_SCALE" FROM sys.columns c INNER JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE c.object_id = OBJECT_ID(?) AND \'\' <> ?';
6010
+                    return 'SELECT c.name AS "COLUMN_NAME", c.is_nullable AS "IS_NULLABLE", t.Name AS "DATA_TYPE", (c.max_length/2) AS "CHARACTER_MAXIMUM_LENGTH", c.precision AS "NUMERIC_PRECISION", c.scale AS "NUMERIC_SCALE", \'\' AS "COLUMN_TYPE" FROM sys.columns c INNER JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE c.object_id = OBJECT_ID(?) AND \'\' <> ?';
5969 6011
             }
5970 6012
         }
5971 6013
 
@@ -6070,7 +6112,7 @@ namespace Tqdev\PhpCrudApi\Database {
6070 6112
             return $foreignKeys;
6071 6113
         }
6072 6114
 
6073
-        public function toJdbcType(string $type, int $size): string
6115
+        public function toJdbcType(string $type, string $size): string
6074 6116
         {
6075 6117
             return $this->typeConverter->toJdbc($type, $size);
6076 6118
         }
@@ -6377,7 +6419,7 @@ namespace Tqdev\PhpCrudApi\Database {
6377 6419
             'geometry' => true,
6378 6420
         ];
6379 6421
 
6380
-        public function toJdbc(string $type, int $size): string
6422
+        public function toJdbc(string $type, string $size): string
6381 6423
         {
6382 6424
             $jdbcType = strtolower($type);
6383 6425
             if (isset($this->toJdbc[$this->driver]["$jdbcType($size)"])) {
@@ -10299,6 +10341,7 @@ namespace Tqdev\PhpCrudApi {
10299 10341
         'username' => 'php-crud-api',
10300 10342
         'password' => 'php-crud-api',
10301 10343
         'database' => 'php-crud-api',
10344
+        'controllers' => 'records,columns,openapi',
10302 10345
     ]);
10303 10346
     $request = RequestFactory::fromGlobals();
10304 10347
     $api = new Api($config);

+ 43
- 1
src/Tqdev/PhpCrudApi/Column/Reflection/ReflectedColumn.php View File

@@ -32,13 +32,55 @@ class ReflectedColumn implements \JsonSerializable
32 32
         $this->sanitize();
33 33
     }
34 34
 
35
+    private static function parseColumnType(string $columnType, int &$length, int &$precision, int &$scale) /*: void*/
36
+    {
37
+        if (!$columnType) {
38
+            return;
39
+        }
40
+        $pos = strpos($columnType, '(');
41
+        if ($pos) {
42
+            $dataSize = rtrim(substr($columnType, $pos + 1), ')');
43
+            if ($length) {
44
+                $length = (int) $dataSize;
45
+            } else {
46
+                $pos = strpos($dataSize, ',');
47
+                if ($pos) {
48
+                    $precision = (int) substr($dataSize, 0, $pos);
49
+                    $scale = (int) substr($dataSize, $pos + 1);
50
+                } else {
51
+                    $precision = (int) $dataSize;
52
+                    $scale = 0;
53
+                }
54
+            }
55
+        }
56
+    }
57
+
58
+    private static function getDataSize(int $length, int $precision, int $scale): string
59
+    {
60
+        $dataSize = '';
61
+        if ($length) {
62
+            $dataSize = $length;
63
+        } elseif ($precision) {
64
+            if ($scale) {
65
+                $dataSize = $precision . ',' . $scale;
66
+            } else {
67
+                $dataSize = $precision;
68
+            }
69
+        }
70
+        return $dataSize;
71
+    }
72
+
35 73
     public static function fromReflection(GenericReflection $reflection, array $columnResult): ReflectedColumn
36 74
     {
37 75
         $name = $columnResult['COLUMN_NAME'];
76
+        $dataType = $columnResult['DATA_TYPE'];
38 77
         $length = (int) $columnResult['CHARACTER_MAXIMUM_LENGTH'];
39
-        $type = $reflection->toJdbcType($columnResult['DATA_TYPE'], $length);
40 78
         $precision = (int) $columnResult['NUMERIC_PRECISION'];
41 79
         $scale = (int) $columnResult['NUMERIC_SCALE'];
80
+        $columnType = $columnResult['COLUMN_TYPE'];
81
+        self::parseColumnType($columnType, $length, $precision, $scale);
82
+        $dataSize = self::getDataSize($length, $precision, $scale);
83
+        $type = $reflection->toJdbcType($dataType, $dataSize);
42 84
         $nullable = in_array(strtoupper($columnResult['IS_NULLABLE']), ['TRUE', 'YES', 'T', 'Y', '1']);
43 85
         $pk = false;
44 86
         $fk = '';

+ 3
- 2
src/Tqdev/PhpCrudApi/Column/ReflectionService.php View File

@@ -26,9 +26,10 @@ class ReflectionService
26 26
 
27 27
     private function database(): ReflectedDatabase
28 28
     {
29
-        if (!$this->database) {
30
-            $this->database = $this->loadDatabase(true);
29
+        if ($this->database) {
30
+            return $this->database;
31 31
         }
32
+        $this->database = $this->loadDatabase(true);
32 33
         return $this->database;
33 34
     }
34 35
 

+ 4
- 4
src/Tqdev/PhpCrudApi/Database/GenericReflection.php View File

@@ -47,11 +47,11 @@ class GenericReflection
47 47
     {
48 48
         switch ($this->driver) {
49 49
             case 'mysql':
50
-                return 'SELECT "COLUMN_NAME", "IS_NULLABLE", "DATA_TYPE", if ("DATA_TYPE"=\'tinyint\' OR "DATA_TYPE"=\'bit\',SUBSTRING_INDEX(SUBSTRING_INDEX("COLUMN_TYPE",\'(\',-1),\')\',1),"CHARACTER_MAXIMUM_LENGTH") as "CHARACTER_MAXIMUM_LENGTH", "NUMERIC_PRECISION", "NUMERIC_SCALE" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "TABLE_SCHEMA" = ?';
50
+                return 'SELECT "COLUMN_NAME", "IS_NULLABLE", "DATA_TYPE", "CHARACTER_MAXIMUM_LENGTH" as "CHARACTER_MAXIMUM_LENGTH", "NUMERIC_PRECISION", "NUMERIC_SCALE", "COLUMN_TYPE" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "TABLE_SCHEMA" = ?';
51 51
             case 'pgsql':
52
-                return 'SELECT a.attname AS "COLUMN_NAME", case when a.attnotnull then \'NO\' else \'YES\' end as "IS_NULLABLE", pg_catalog.format_type(a.atttypid, -1) as "DATA_TYPE", case when a.atttypmod < 0 then NULL else a.atttypmod-4 end as "CHARACTER_MAXIMUM_LENGTH", case when a.atttypid != 1700 then NULL else ((a.atttypmod - 4) >> 16) & 65535 end as "NUMERIC_PRECISION", case when a.atttypid != 1700 then NULL else (a.atttypmod - 4) & 65535 end as "NUMERIC_SCALE" FROM pg_attribute a JOIN pg_class pgc ON pgc.oid = a.attrelid WHERE pgc.relname = ? AND \'\' <> ? AND a.attnum > 0 AND NOT a.attisdropped;';
52
+                return 'SELECT a.attname AS "COLUMN_NAME", case when a.attnotnull then \'NO\' else \'YES\' end as "IS_NULLABLE", pg_catalog.format_type(a.atttypid, -1) as "DATA_TYPE", case when a.atttypmod < 0 then NULL else a.atttypmod-4 end as "CHARACTER_MAXIMUM_LENGTH", case when a.atttypid != 1700 then NULL else ((a.atttypmod - 4) >> 16) & 65535 end as "NUMERIC_PRECISION", case when a.atttypid != 1700 then NULL else (a.atttypmod - 4) & 65535 end as "NUMERIC_SCALE", \'\' AS "COLUMN_TYPE" FROM pg_attribute a JOIN pg_class pgc ON pgc.oid = a.attrelid WHERE pgc.relname = ? AND \'\' <> ? AND a.attnum > 0 AND NOT a.attisdropped;';
53 53
             case 'sqlsrv':
54
-                return 'SELECT c.name AS "COLUMN_NAME", c.is_nullable AS "IS_NULLABLE", t.Name AS "DATA_TYPE", (c.max_length/2) AS "CHARACTER_MAXIMUM_LENGTH", c.precision AS "NUMERIC_PRECISION", c.scale AS "NUMERIC_SCALE" FROM sys.columns c INNER JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE c.object_id = OBJECT_ID(?) AND \'\' <> ?';
54
+                return 'SELECT c.name AS "COLUMN_NAME", c.is_nullable AS "IS_NULLABLE", t.Name AS "DATA_TYPE", (c.max_length/2) AS "CHARACTER_MAXIMUM_LENGTH", c.precision AS "NUMERIC_PRECISION", c.scale AS "NUMERIC_SCALE", \'\' AS "COLUMN_TYPE" FROM sys.columns c INNER JOIN sys.types t ON c.user_type_id = t.user_type_id WHERE c.object_id = OBJECT_ID(?) AND \'\' <> ?';
55 55
         }
56 56
     }
57 57
 
@@ -156,7 +156,7 @@ class GenericReflection
156 156
         return $foreignKeys;
157 157
     }
158 158
 
159
-    public function toJdbcType(string $type, int $size): string
159
+    public function toJdbcType(string $type, string $size): string
160 160
     {
161 161
         return $this->typeConverter->toJdbc($type, $size);
162 162
     }

+ 1
- 1
src/Tqdev/PhpCrudApi/Database/TypeConverter.php View File

@@ -166,7 +166,7 @@ class TypeConverter
166 166
         'geometry' => true,
167 167
     ];
168 168
 
169
-    public function toJdbc(string $type, int $size): string
169
+    public function toJdbc(string $type, string $size): string
170 170
     {
171 171
         $jdbcType = strtolower($type);
172 172
         if (isset($this->toJdbc[$this->driver]["$jdbcType($size)"])) {

+ 1
- 0
src/index.php View File

@@ -13,6 +13,7 @@ $config = new Config([
13 13
     'username' => 'php-crud-api',
14 14
     'password' => 'php-crud-api',
15 15
     'database' => 'php-crud-api',
16
+    'controllers' => 'records,columns,openapi',
16 17
 ]);
17 18
 $request = RequestFactory::fromGlobals();
18 19
 $api = new Api($config);

Loading…
Cancel
Save