|
@@ -5936,45 +5936,60 @@ namespace Tqdev\PhpCrudApi\Database {
|
5936
|
5936
|
public function getIgnoredTables(): array
|
5937
|
5937
|
{
|
5938
|
5938
|
switch ($this->driver) {
|
5939
|
|
- case 'mysql':return [];
|
5940
|
|
- case 'pgsql':return ['spatial_ref_sys', 'raster_columns', 'raster_overviews', 'geography_columns', 'geometry_columns'];
|
5941
|
|
- case 'sqlsrv':return [];
|
|
5939
|
+ case 'mysql':
|
|
5940
|
+ return [];
|
|
5941
|
+ case 'pgsql':
|
|
5942
|
+ return ['spatial_ref_sys', 'raster_columns', 'raster_overviews', 'geography_columns', 'geometry_columns'];
|
|
5943
|
+ case 'sqlsrv':
|
|
5944
|
+ return [];
|
5942
|
5945
|
}
|
5943
|
5946
|
}
|
5944
|
5947
|
|
5945
|
5948
|
private function getTablesSQL(): string
|
5946
|
5949
|
{
|
5947
|
5950
|
switch ($this->driver) {
|
5948
|
|
- case 'mysql':return 'SELECT "TABLE_NAME", "TABLE_TYPE" FROM "INFORMATION_SCHEMA"."TABLES" WHERE "TABLE_TYPE" IN (\'BASE TABLE\' , \'VIEW\') AND "TABLE_SCHEMA" = ? ORDER BY BINARY "TABLE_NAME"';
|
5949
|
|
- case 'pgsql':return 'SELECT c.relname as "TABLE_NAME", c.relkind as "TABLE_TYPE" FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN (\'r\', \'v\') AND n.nspname <> \'pg_catalog\' AND n.nspname <> \'information_schema\' AND n.nspname !~ \'^pg_toast\' AND pg_catalog.pg_table_is_visible(c.oid) AND \'\' <> ? ORDER BY "TABLE_NAME";';
|
5950
|
|
- case 'sqlsrv':return 'SELECT o.name as "TABLE_NAME", o.xtype as "TABLE_TYPE" FROM sysobjects o WHERE o.xtype IN (\'U\', \'V\') ORDER BY "TABLE_NAME"';
|
|
5951
|
+ case 'mysql':
|
|
5952
|
+ return 'SELECT "TABLE_NAME", "TABLE_TYPE" FROM "INFORMATION_SCHEMA"."TABLES" WHERE "TABLE_TYPE" IN (\'BASE TABLE\' , \'VIEW\') AND "TABLE_SCHEMA" = ? ORDER BY BINARY "TABLE_NAME"';
|
|
5953
|
+ case 'pgsql':
|
|
5954
|
+ return 'SELECT c.relname as "TABLE_NAME", c.relkind as "TABLE_TYPE" FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN (\'r\', \'v\') AND n.nspname <> \'pg_catalog\' AND n.nspname <> \'information_schema\' AND n.nspname !~ \'^pg_toast\' AND pg_catalog.pg_table_is_visible(c.oid) AND \'\' <> ? ORDER BY "TABLE_NAME";';
|
|
5955
|
+ case 'sqlsrv':
|
|
5956
|
+ return 'SELECT o.name as "TABLE_NAME", o.xtype as "TABLE_TYPE" FROM sysobjects o WHERE o.xtype IN (\'U\', \'V\') ORDER BY "TABLE_NAME"';
|
5951
|
5957
|
}
|
5952
|
5958
|
}
|
5953
|
5959
|
|
5954
|
5960
|
private function getTableColumnsSQL(): string
|
5955
|
5961
|
{
|
5956
|
5962
|
switch ($this->driver) {
|
5957
|
|
- case 'mysql':return 'SELECT "COLUMN_NAME", "IS_NULLABLE", "DATA_TYPE", "CHARACTER_MAXIMUM_LENGTH", "NUMERIC_PRECISION", "NUMERIC_SCALE" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "TABLE_SCHEMA" = ?';
|
5958
|
|
- case 'pgsql':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;';
|
5959
|
|
- case 'sqlsrv':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 \'\' <> ?';
|
|
5963
|
+ 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" = ?';
|
|
5965
|
+ 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;';
|
|
5967
|
+ 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 \'\' <> ?';
|
5960
|
5969
|
}
|
5961
|
5970
|
}
|
5962
|
5971
|
|
5963
|
5972
|
private function getTablePrimaryKeysSQL(): string
|
5964
|
5973
|
{
|
5965
|
5974
|
switch ($this->driver) {
|
5966
|
|
- case 'mysql':return 'SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."KEY_COLUMN_USAGE" WHERE "CONSTRAINT_NAME" = \'PRIMARY\' AND "TABLE_NAME" = ? AND "TABLE_SCHEMA" = ?';
|
5967
|
|
- case 'pgsql':return 'SELECT a.attname AS "COLUMN_NAME" FROM pg_attribute a JOIN pg_constraint c ON (c.conrelid, c.conkey[1]) = (a.attrelid, a.attnum) JOIN pg_class pgc ON pgc.oid = a.attrelid WHERE pgc.relname = ? AND \'\' <> ? AND c.contype = \'p\'';
|
5968
|
|
- case 'sqlsrv':return 'SELECT c.NAME as "COLUMN_NAME" FROM sys.key_constraints kc inner join sys.objects t on t.object_id = kc.parent_object_id INNER JOIN sys.index_columns ic ON kc.parent_object_id = ic.object_id and kc.unique_index_id = ic.index_id INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE kc.type = \'PK\' and t.object_id = OBJECT_ID(?) and \'\' <> ?';
|
|
5975
|
+ case 'mysql':
|
|
5976
|
+ return 'SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."KEY_COLUMN_USAGE" WHERE "CONSTRAINT_NAME" = \'PRIMARY\' AND "TABLE_NAME" = ? AND "TABLE_SCHEMA" = ?';
|
|
5977
|
+ case 'pgsql':
|
|
5978
|
+ return 'SELECT a.attname AS "COLUMN_NAME" FROM pg_attribute a JOIN pg_constraint c ON (c.conrelid, c.conkey[1]) = (a.attrelid, a.attnum) JOIN pg_class pgc ON pgc.oid = a.attrelid WHERE pgc.relname = ? AND \'\' <> ? AND c.contype = \'p\'';
|
|
5979
|
+ case 'sqlsrv':
|
|
5980
|
+ return 'SELECT c.NAME as "COLUMN_NAME" FROM sys.key_constraints kc inner join sys.objects t on t.object_id = kc.parent_object_id INNER JOIN sys.index_columns ic ON kc.parent_object_id = ic.object_id and kc.unique_index_id = ic.index_id INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE kc.type = \'PK\' and t.object_id = OBJECT_ID(?) and \'\' <> ?';
|
5969
|
5981
|
}
|
5970
|
5982
|
}
|
5971
|
5983
|
|
5972
|
5984
|
private function getTableForeignKeysSQL(): string
|
5973
|
5985
|
{
|
5974
|
5986
|
switch ($this->driver) {
|
5975
|
|
- case 'mysql':return 'SELECT "COLUMN_NAME", "REFERENCED_TABLE_NAME" FROM "INFORMATION_SCHEMA"."KEY_COLUMN_USAGE" WHERE "REFERENCED_TABLE_NAME" IS NOT NULL AND "TABLE_NAME" = ? AND "TABLE_SCHEMA" = ?';
|
5976
|
|
- case 'pgsql':return 'SELECT a.attname AS "COLUMN_NAME", c.confrelid::regclass::text AS "REFERENCED_TABLE_NAME" FROM pg_attribute a JOIN pg_constraint c ON (c.conrelid, c.conkey[1]) = (a.attrelid, a.attnum) JOIN pg_class pgc ON pgc.oid = a.attrelid WHERE pgc.relname = ? AND \'\' <> ? AND c.contype = \'f\'';
|
5977
|
|
- case 'sqlsrv':return 'SELECT COL_NAME(fc.parent_object_id, fc.parent_column_id) AS "COLUMN_NAME", OBJECT_NAME (f.referenced_object_id) AS "REFERENCED_TABLE_NAME" FROM sys.foreign_keys AS f INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id WHERE f.parent_object_id = OBJECT_ID(?) and \'\' <> ?';
|
|
5987
|
+ case 'mysql':
|
|
5988
|
+ return 'SELECT "COLUMN_NAME", "REFERENCED_TABLE_NAME" FROM "INFORMATION_SCHEMA"."KEY_COLUMN_USAGE" WHERE "REFERENCED_TABLE_NAME" IS NOT NULL AND "TABLE_NAME" = ? AND "TABLE_SCHEMA" = ?';
|
|
5989
|
+ case 'pgsql':
|
|
5990
|
+ return 'SELECT a.attname AS "COLUMN_NAME", c.confrelid::regclass::text AS "REFERENCED_TABLE_NAME" FROM pg_attribute a JOIN pg_constraint c ON (c.conrelid, c.conkey[1]) = (a.attrelid, a.attnum) JOIN pg_class pgc ON pgc.oid = a.attrelid WHERE pgc.relname = ? AND \'\' <> ? AND c.contype = \'f\'';
|
|
5991
|
+ case 'sqlsrv':
|
|
5992
|
+ return 'SELECT COL_NAME(fc.parent_object_id, fc.parent_column_id) AS "COLUMN_NAME", OBJECT_NAME (f.referenced_object_id) AS "REFERENCED_TABLE_NAME" FROM sys.foreign_keys AS f INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id WHERE f.parent_object_id = OBJECT_ID(?) and \'\' <> ?';
|
5978
|
5993
|
}
|
5979
|
5994
|
}
|
5980
|
5995
|
|
|
@@ -6015,6 +6030,21 @@ namespace Tqdev\PhpCrudApi\Database {
|
6015
|
6030
|
$result['IS_NULLABLE'] = false;
|
6016
|
6031
|
}
|
6017
|
6032
|
}
|
|
6033
|
+ if ($this->driver == 'mysql') {
|
|
6034
|
+ foreach ($results as &$result) {
|
|
6035
|
+ // mysql does not properly reflect display width of types
|
|
6036
|
+ preg_match('|([a-z]+)(\(([0-9]+)(,([0-9]+))?\))?|', $result['DATA_TYPE'], $matches);
|
|
6037
|
+ $result['DATA_TYPE'] = $matches[1];
|
|
6038
|
+ if (!$result['CHARACTER_MAXIMUM_LENGTH']) {
|
|
6039
|
+ if (isset($matches[3])) {
|
|
6040
|
+ $result['NUMERIC_PRECISION'] = $matches[3];
|
|
6041
|
+ }
|
|
6042
|
+ if (isset($matches[5])) {
|
|
6043
|
+ $result['NUMERIC_SCALE'] = $matches[5];
|
|
6044
|
+ }
|
|
6045
|
+ }
|
|
6046
|
+ }
|
|
6047
|
+ }
|
6018
|
6048
|
return $results;
|
6019
|
6049
|
}
|
6020
|
6050
|
|
|
@@ -6195,7 +6225,7 @@ namespace Tqdev\PhpCrudApi\Database {
|
6195
|
6225
|
private $fromJdbc = [
|
6196
|
6226
|
'mysql' => [
|
6197
|
6227
|
'clob' => 'longtext',
|
6198
|
|
- 'boolean' => 'bit',
|
|
6228
|
+ 'boolean' => 'tinyint',
|
6199
|
6229
|
'blob' => 'longblob',
|
6200
|
6230
|
'timestamp' => 'datetime',
|
6201
|
6231
|
],
|
|
@@ -6228,7 +6258,8 @@ namespace Tqdev\PhpCrudApi\Database {
|
6228
|
6258
|
'timestamp_with_timezone' => 'timestamp',
|
6229
|
6259
|
],
|
6230
|
6260
|
'mysql' => [
|
6231
|
|
- 'bit' => 'boolean',
|
|
6261
|
+ 'tinyint(1)' => 'boolean',
|
|
6262
|
+ 'bit(1)' => 'boolean',
|
6232
|
6263
|
'tinyblob' => 'blob',
|
6233
|
6264
|
'mediumblob' => 'blob',
|
6234
|
6265
|
'longblob' => 'blob',
|
|
@@ -9798,18 +9829,34 @@ namespace Tqdev\PhpCrudApi {
|
9798
|
9829
|
|
9799
|
9830
|
private function addParsedBody(ServerRequestInterface $request): ServerRequestInterface
|
9800
|
9831
|
{
|
9801
|
|
- $body = $request->getBody();
|
9802
|
|
- if ($body->isReadable() && $body->isSeekable()) {
|
9803
|
|
- $contents = $body->getContents();
|
9804
|
|
- $body->rewind();
|
9805
|
|
- if ($contents) {
|
9806
|
|
- $parsedBody = $this->parseBody($contents);
|
9807
|
|
- $request = $request->withParsedBody($parsedBody);
|
|
9832
|
+ $parsedBody = $request->getParsedBody();
|
|
9833
|
+ if ($parsedBody) {
|
|
9834
|
+ $request = $this->applySlim3Hack($request);
|
|
9835
|
+ } else {
|
|
9836
|
+ $body = $request->getBody();
|
|
9837
|
+ if ($body->isReadable() && $body->isSeekable()) {
|
|
9838
|
+ $contents = $body->getContents();
|
|
9839
|
+ $body->rewind();
|
|
9840
|
+ if ($contents) {
|
|
9841
|
+ $parsedBody = $this->parseBody($contents);
|
|
9842
|
+ $request = $request->withParsedBody($parsedBody);
|
|
9843
|
+ }
|
9808
|
9844
|
}
|
9809
|
9845
|
}
|
9810
|
9846
|
return $request;
|
9811
|
9847
|
}
|
9812
|
9848
|
|
|
9849
|
+ private function applySlim3Hack(ServerRequestInterface $request): ServerRequestInterface
|
|
9850
|
+ {
|
|
9851
|
+ if (get_class($request) == 'Slim\Http\Request') {
|
|
9852
|
+ $parsedBody = $request->getParsedBody();
|
|
9853
|
+ $contents = json_encode($parsedBody);
|
|
9854
|
+ $parsedBody = $this->parseBody($contents);
|
|
9855
|
+ $request = $request->withParsedBody($parsedBody);
|
|
9856
|
+ }
|
|
9857
|
+ return $request;
|
|
9858
|
+ }
|
|
9859
|
+
|
9813
|
9860
|
public function handle(ServerRequestInterface $request): ResponseInterface
|
9814
|
9861
|
{
|
9815
|
9862
|
$response = null;
|