| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- <?php
- Lib::loadClass('Core_StorageBase');
- Lib::loadClass('Core_StorageFactory');
- class Core_Storage_Pgsql extends Core_StorageBase {
- protected $_databaseName = '';
- protected $_zasob_id = 0;
- protected $_pdo = null;
- public function __construct($pdo) {
- $this->_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 "<div class=\"alert alert-warning\">Storage type '{$fieldStruct['Type']}' not recognized</div>";
- // 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);
- }
- }
|