api de gestion de ticket, basé sur php-crud-api. Le but est de décorrélé les outils de gestion des données, afin
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GenericReflection.php 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. namespace Tqdev\PhpCrudApi\Database;
  3. class GenericReflection
  4. {
  5. private $pdo;
  6. private $driver;
  7. private $database;
  8. private $typeConverter;
  9. public function __construct(\PDO $pdo, String $driver, String $database)
  10. {
  11. $this->pdo = $pdo;
  12. $this->driver = $driver;
  13. $this->database = $database;
  14. $this->typeConverter = new TypeConverter($driver);
  15. }
  16. public function getIgnoredTables(): array
  17. {
  18. switch ($this->driver) {
  19. case 'mysql':return [];
  20. case 'pgsql':return ['spatial_ref_sys'];
  21. case 'sqlsrv':return [];
  22. }
  23. }
  24. private function getTablesSQL(): String
  25. {
  26. switch ($this->driver) {
  27. case 'mysql':return 'SELECT "TABLE_NAME" FROM "INFORMATION_SCHEMA"."TABLES" WHERE "TABLE_TYPE" IN (\'BASE TABLE\') AND "TABLE_SCHEMA" = ? ORDER BY BINARY "TABLE_NAME"';
  28. case 'pgsql':return 'SELECT c.relname as "TABLE_NAME" FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN (\'r\') 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";';
  29. case 'sqlsrv':return 'SELECT o.name as "TABLE_NAME" FROM sysobjects o WHERE o.xtype = \'U\' ORDER BY "TABLE_NAME"';
  30. }
  31. }
  32. private function getTableColumnsSQL(): String
  33. {
  34. switch ($this->driver) {
  35. 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" = ?';
  36. 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;';
  37. 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 \'\' <> ?';
  38. }
  39. }
  40. private function getTablePrimaryKeysSQL(): String
  41. {
  42. switch ($this->driver) {
  43. case 'mysql':return 'SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."KEY_COLUMN_USAGE" WHERE "CONSTRAINT_NAME" = \'PRIMARY\' AND "TABLE_NAME" = ? AND "TABLE_SCHEMA" = ?';
  44. 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\'';
  45. 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 \'\' <> ?';
  46. }
  47. }
  48. private function getTableForeignKeysSQL(): String
  49. {
  50. switch ($this->driver) {
  51. 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" = ?';
  52. 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\'';
  53. 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 \'\' <> ?';
  54. }
  55. }
  56. public function getDatabaseName(): String
  57. {
  58. return $this->database;
  59. }
  60. public function getTables(): array
  61. {
  62. $stmt = $this->pdo->prepare($this->getTablesSQL());
  63. $stmt->execute([$this->database]);
  64. return $stmt->fetchAll();
  65. }
  66. public function getTableColumns(String $tableName): array
  67. {
  68. $stmt = $this->pdo->prepare($this->getTableColumnsSQL());
  69. $stmt->execute([$tableName, $this->database]);
  70. return $stmt->fetchAll();
  71. }
  72. public function getTablePrimaryKeys(String $tableName): array
  73. {
  74. $stmt = $this->pdo->prepare($this->getTablePrimaryKeysSQL());
  75. $stmt->execute([$tableName, $this->database]);
  76. $results = $stmt->fetchAll();
  77. $primaryKeys = [];
  78. foreach ($results as $result) {
  79. $primaryKeys[] = $result['COLUMN_NAME'];
  80. }
  81. return $primaryKeys;
  82. }
  83. public function getTableForeignKeys(String $tableName): array
  84. {
  85. $stmt = $this->pdo->prepare($this->getTableForeignKeysSQL());
  86. $stmt->execute([$tableName, $this->database]);
  87. $results = $stmt->fetchAll();
  88. $foreignKeys = [];
  89. foreach ($results as $result) {
  90. $foreignKeys[$result['COLUMN_NAME']] = $result['REFERENCED_TABLE_NAME'];
  91. }
  92. return $foreignKeys;
  93. }
  94. public function toJdbcType(String $type, int $size): String
  95. {
  96. return $this->typeConverter->toJdbc($type, $size);
  97. }
  98. }