_pdo = $pdo; $this->_databaseName = $pdo->getDatabaseName(); $this->_zasob_id = $pdo->getZasobId(); } public function getTableStruct($tblName) { $structRaw = $this->_getPgsqlStructureRaw($schemaName = 'g', $tblName); DBG::table("struct", $structRaw, __CLASS__, __FUNCTION__, __LINE__); throw new Exception("TODO: C." . __CLASS__ . " F." . __FUNCTION__); $sql = " -- show fields from {$tblName} select cols.COLUMN_NAME as name , cols.DATA_TYPE as type , if('YES' = cols.IS_NULLABLE, 1, 0) as is_nullable , cols.COLUMN_DEFAULT as default_value , if(cols.COLUMN_DEFAULT is null, 1, 0) as default_is_null , cols.CHARACTER_MAXIMUM_LENGTH as max_length , cols.NUMERIC_PRECISION as num_precision , cols.NUMERIC_SCALE as num_scale , cols.CHARACTER_SET_NAME as char_encoding -- latin2 , cols.COLLATION_NAME as char_collation -- latin2_general_ci , cols.EXTRA as extra , cols.COLUMN_TYPE as raw_storage_type -- , cols.* from INFORMATION_SCHEMA.COLUMNS cols where cols.TABLE_SCHEMA like :db_name and cols.TABLE_NAME like :tbl_name "; $sth = $this->_pdo->prepare($sql); $sth->bindValue(':db_name', $this->_pdo->getDatabaseName(), PDO::PARAM_STR); $sth->bindValue(':tbl_name', $tblName, PDO::PARAM_STR); $sth->execute(); $structRaw = $sth->fetchAll(); if (empty($structRaw)) throw new Exception("Empty struct for table '{$tblName}'", 404); foreach ($structRaw as $field) { $struct[$field['name']] = $field; } return $struct; } protected function _getTableStruct($tblName) {// ? $tblStructRaw = $this->getTableStructRaw($tblName); $tblStruct = array(); foreach ($tblStructRaw as $fieldStruct) { $fldName = $fieldStruct['column_name']; $storageType = ''; if ('integer' == $fieldStruct['data_type'] || 'bigint' == $fieldStruct['data_type'] || 'smallint' == $fieldStruct['data_type'] ) { $storageType = Core_StorageFactory::getType('Integer'); } else if ('character varying' == $fieldStruct['data_type'] || 'character' == $fieldStruct['data_type'] ) { $storageType = Core_StorageFactory::getType('String'); $storageType->setMaxLength($fieldStruct['character_maximum_length']); } else if ('numeric' == $fieldStruct['data_type'] || 'decimal' == $fieldStruct['data_type'] ) { $storageType = Core_StorageFactory::getType('Decimal'); } else if ('real' == $fieldStruct['data_type'] || 'double precision' == $fieldStruct['data_type'] ) { $storageType = Core_StorageFactory::getType('Double'); } else if ('text' == $fieldStruct['data_type']) { $storageType = Core_StorageFactory::getType('Text'); } else if ('"char"' == $fieldStruct['data_type']) { $storageType = Core_StorageFactory::getType('String'); $storageType->setMaxLength(1); } else if ('date' == $fieldStruct['data_type']) { $storageType = Core_StorageFactory::getType('Date'); } else if ('timestamp without time zone' == $fieldStruct['data_type']) { $storageType = Core_StorageFactory::getType('DateTime'); } else if ('timestamp with time zone' == $fieldStruct['data_type']) { $storageType = Core_StorageFactory::getType('DateTime'); } else if ('USER-DEFINED' == $fieldStruct['data_type']) { if ('geometry' == $fieldStruct['udt_name']) { $storageType = Core_StorageFactory::getType('Geometry'); $rawStructure = $this->_getStructureRaw('public', $tblName, $fldName); if (!empty($rawStructure[0]['type'])) { $spatialType = $rawStructure[0]['type']; $storageType->setSpatialType($spatialType); } } else { $storageType = Core_StorageFactory::getType('Unknown'); $storageType->setRawType(array('data_type'=>$fieldStruct['data_type'], 'udt_name'=>$fieldStruct['udt_name'])); } } else { $storageType = Core_StorageFactory::getType('Unknown'); $storageType->setRawType(array('data_type'=>$fieldStruct['data_type'], 'udt_name'=>$fieldStruct['udt_name'])); } if (!$storageType) { echo "
Storage type '{$fieldStruct['Type']}' not recognized
"; // TODO: throw new Exception("Storage type '{$fieldStruct['Type']}' not recognized"); } if ($fieldStruct['is_primary_key'] > 0) { $storageType->setPrimaryKey(true); } $vFldNillable = false; if ('YES' == $fieldStruct['is_nullable']) { $vFldNillable = true; } else if ('NO' == $fieldStruct['is_nullable'] && $fieldStruct['is_primary_key'] > 0 && 'nextval(' == substr($fieldStruct['column_default'], 0, 8) ) { $vFldNillable = true; } $storageType->setNillable($vFldNillable); $vFldDefault = $fieldStruct['column_default']; if (!empty($vFldDefault)) { if ('::"char"' == substr($vFldDefault, -8)) { $vFldDefault = substr($vFldDefault, 1, -9); $storageType->setDefault($vFldDefault); } else if ('::"text"' == substr($vFldDefault, -8)) { $vFldDefault = substr($vFldDefault, 1, -9); $storageType->setDefault($vFldDefault); } else if ('::bpchar' == substr($vFldDefault, -8)) { $vFldDefault = substr($vFldDefault, 1, -9); $storageType->setDefault($vFldDefault); } else if ('::character varying' == substr($vFldDefault, -19)) { $vFldDefault = substr($vFldDefault, 1, -20); $storageType->setDefault($vFldDefault); } else if (is_numeric($vFldDefault)) { $storageType->setDefault($vFldDefault); } else if ('now()' == $vFldDefault) { // TODO: default = now() } } else if ('0' === $vFldDefault) { $storageType->setDefault('0'); } $tblStruct[$fldName] = $storageType; } return $tblStruct; } public function getTableStructRaw($tblName) {// ? $tblNamePattern = '/^[a-zA-Z0-9_]+$/'; if (!preg_match($tblNamePattern, $tblName)) { throw new Exception("Table name not allowed"); } $sqlTblName = $tblName; $sql = "select * from information_schema.columns where table_name='{$sqlTblName}'"; $sqlAllPrimaryKeys = " select tc.table_schema, tc.table_name, kc.column_name from information_schema.table_constraints tc, information_schema.key_column_usage kc where tc.constraint_type = 'PRIMARY KEY' and kc.table_name = tc.table_name and kc.table_schema = tc.table_schema and kc.constraint_name = tc.constraint_name order by 1, 2; "; $sql = "select cols.* , (select count(kc.column_name) from information_schema.table_constraints tc join information_schema.key_column_usage kc on(kc.table_name = tc.table_name and kc.table_schema = tc.table_schema and kc.constraint_name = tc.constraint_name) where tc.constraint_type = 'PRIMARY KEY' and tc.table_name = cols.table_name and kc.column_name = cols.column_name ) as is_primary_key from information_schema.columns cols where cols.table_name='{$sqlTblName}' "; return $this->fetchAllAssoc($sql); } public function getTableListWithInfo() { return $this->_getPgsqlStructureRaw(); } public function _getPgsqlStructureRaw($schemaName = 'public', $tableName = '', $fieldName = '') { $rawStructureList = array(); $sqlWhereAndSchemaName = ($schemaName) ? " and n.nspname='{$schemaName}' " : ''; $sqlWhereAndTableName = ($tableName) ? " and c.relname='{$tableName}' " : ''; $sqlWhereAndFieldName = ($fieldName) ? " and f.attname='{$fieldName}' " : ''; $sql = " select c.relname as table_name, f.attnum as number, f.attname as name, f.attnum, f.attnotnull as notnull, f.atttypid, f.atttypmod, pg_catalog.format_type(f.atttypid,f.atttypmod) as type, case when p.contype = 'p' then 1 else 0 end as primarykey, case when p.contype = 'u' then 1 else 0 end as uniquekey, case when p.contype = 'f' then g.relname end as foreignkey, case when p.contype = 'f' then p.confkey end as foreignkey_fieldnum, case when p.contype = 'f' then g.relname end as foreignkey, case when p.contype = 'f' then p.conkey end as foreignkey_connnum, case when f.atthasdef = 't' then d.adsrc end as default from pg_attribute f join pg_class c on c.oid = f.attrelid join pg_type t on t.oid = f.atttypid left join pg_attrdef d on d.adrelid = c.oid and d.adnum = f.attnum left join pg_namespace n on n.oid = c.relnamespace left join pg_constraint p on p.conrelid = c.oid and f.attnum = any (p.conkey) left join pg_class as g on p.confrelid = g.oid where c.relkind = 'r'::char {$sqlWhereAndSchemaName} {$sqlWhereAndTableName} {$sqlWhereAndFieldName} and f.attnum > 0 order by c.relname, number "; return $this->_pdo->fetchAll($sql); } public function getTableList() { return array_filter($this->getTableFullList(), function($row) { return ('BASE TABLE' == $row['table_type']); }); } public function getViewList() { return array_filter($this->getTableFullList(), function($row) { return ('VIEW' == $row['table_type']); }); } public function getTableFullList() { return array_map(function($row) { $row['table_name'] = strtolower($row['table_name']); return $row; }, $this->_pdo->fetchAll(" select table_name, table_type from information_schema.tables where table_schema not in ('pg_catalog', 'information_schema') ")); } public function fetchAllAssoc($sql) {// ? if (empty($sql)) { throw new Exception("Empty query"); } $stmt = $this->_pdo->query($sql); return $stmt->fetchAll(PDO::FETCH_ASSOC); } }