Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
103621ad
Commit
103621ad
authored
May 30, 2013
by
Gevik Babakhani
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Savepoint: WIP implementing columns
parent
4602b575
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
204 additions
and
7 deletions
+204
-7
PDO.php
framework/yii/db/pgsql/PDO.php
+31
-4
Schema.php
framework/yii/db/pgsql/Schema.php
+160
-2
postgres.sql
tests/unit/data/postgres.sql
+13
-1
No files found.
framework/yii/db/pgsql/PDO.php
View file @
103621ad
...
@@ -18,16 +18,33 @@ namespace yii\db\pgsql;
...
@@ -18,16 +18,33 @@ namespace yii\db\pgsql;
*/
*/
class
PDO
extends
\PDO
{
class
PDO
extends
\PDO
{
const
OPT_SEARCH_PATH
=
'search_path'
;
const
OPT_DEFAULT_SCHEMA
=
'default_schema'
;
const
DEFAULT_SCHEMA
=
'public'
;
private
$_currentDatabase
=
null
;
/**
/**
* Here we override the default PDO constructor in order to
* Here we override the default PDO constructor in order to
* find and set the default schema search path.
* find and set the default schema search path.
*/
*/
public
function
__construct
(
$dsn
,
$username
,
$passwd
,
$options
)
{
public
function
__construct
(
$dsn
,
$username
,
$passwd
,
$options
)
{
$searchPath
=
null
;
$searchPath
=
null
;
if
(
is_array
(
$options
)
&&
isset
(
$options
[
'search_path'
]))
{
if
(
is_array
(
$options
))
{
$matches
=
null
;
if
(
isset
(
$options
[
self
::
OPT_SEARCH_PATH
]))
{
if
(
preg_match
(
"/(\s?)+(\w)+((\s+)?,(\s+)?\w+)*/"
,
$options
[
'search_path'
],
$matches
)
===
1
)
{
$matches
=
null
;
$searchPath
=
$matches
[
0
];
if
(
preg_match
(
"/(\s?)+(\w)+((\s+)?,(\s+)?\w+)*/"
,
$options
[
self
::
OPT_SEARCH_PATH
],
$matches
)
===
1
)
{
$searchPath
=
$matches
[
0
];
}
}
if
(
isset
(
$options
[
self
::
OPT_DEFAULT_SCHEMA
]))
{
$schema
=
trim
(
$options
[
self
::
OPT_DEFAULT_SCHEMA
]);
if
(
$schema
!==
''
)
{
Schema
::
$DEFAULT_SCHEMA
=
$schema
;
}
}
if
(
Schema
::
$DEFAULT_SCHEMA
===
null
||
Schema
::
$DEFAULT_SCHEMA
===
''
)
{
Schema
::
$DEFAULT_SCHEMA
=
self
::
DEFAULT_SCHEMA
;
}
}
}
}
parent
::
__construct
(
$dsn
,
$username
,
$passwd
,
$options
);
parent
::
__construct
(
$dsn
,
$username
,
$passwd
,
$options
);
...
@@ -37,6 +54,16 @@ class PDO extends \PDO {
...
@@ -37,6 +54,16 @@ class PDO extends \PDO {
}
}
/**
/**
* Returns the name of the current (connected) database
* @return string
*/
public
function
getCurrentDatabase
()
{
if
(
is_null
(
$this
->
_currentDatabase
))
{
return
$this
->
query
(
'select current_database()'
)
->
fetchColumn
();
}
}
/**
* Sets the schema search path of the current users session.
* Sets the schema search path of the current users session.
* The syntax of the path is a comma separated string with
* The syntax of the path is a comma separated string with
* your custom search path at the beginning and the "public"
* your custom search path at the beginning and the "public"
...
...
framework/yii/db/pgsql/Schema.php
View file @
103621ad
...
@@ -12,7 +12,8 @@ use yii\db\TableSchema;
...
@@ -12,7 +12,8 @@ use yii\db\TableSchema;
use
yii\db\ColumnSchema
;
use
yii\db\ColumnSchema
;
/**
/**
* Schema is the class for retrieving metadata from a PostgreSQL database (version 9.x and above).
* Schema is the class for retrieving metadata from a PostgreSQL database
* (version 9.x and above).
*
*
* @author Gevik Babakhani <gevikb@gmail.com>
* @author Gevik Babakhani <gevikb@gmail.com>
* @since 2.0
* @since 2.0
...
@@ -20,6 +21,85 @@ use yii\db\ColumnSchema;
...
@@ -20,6 +21,85 @@ use yii\db\ColumnSchema;
class
Schema
extends
\yii\db\Schema
{
class
Schema
extends
\yii\db\Schema
{
/**
/**
* The default schema used for the current session. This value is
* automatically set to "public" by the PDO driver.
* @var string
*/
public
static
$DEFAULT_SCHEMA
;
/**
* @var array mapping from physical column types (keys) to abstract
* column types (values)
*/
public
$typeMap
=
array
(
'abstime'
=>
self
::
TYPE_TIMESTAMP
,
//'aclitem' => self::TYPE_STRING,
'bit'
=>
self
::
TYPE_STRING
,
'boolean'
=>
self
::
TYPE_BOOLEAN
,
'box'
=>
self
::
TYPE_STRING
,
'character'
=>
self
::
TYPE_STRING
,
'bytea'
=>
self
::
TYPE_BINARY
,
'char'
=>
self
::
TYPE_STRING
,
//'cid' => self::TYPE_STRING,
'cidr'
=>
self
::
TYPE_STRING
,
'circle'
=>
self
::
TYPE_STRING
,
'date'
=>
self
::
TYPE_DATE
,
//'daterange' => self::TYPE_STRING,
'real'
=>
self
::
TYPE_FLOAT
,
'double precision'
=>
self
::
TYPE_DECIMAL
,
//'gtsvector' => self::TYPE_STRING,
'inet'
=>
self
::
TYPE_STRING
,
'smallint'
=>
self
::
TYPE_SMALLINT
,
'integer'
=>
self
::
TYPE_INTEGER
,
//'int4range' => self::TYPE_STRING, //unknown
'bigint'
=>
self
::
TYPE_BIGINT
,
//'int8range' => self::TYPE_STRING, // unknown
'interval'
=>
self
::
TYPE_STRING
,
'json'
=>
self
::
TYPE_STRING
,
'line'
=>
self
::
TYPE_STRING
,
//'lseg' => self::TYPE_STRING,
'macaddr'
=>
self
::
TYPE_STRING
,
'money'
=>
self
::
TYPE_MONEY
,
'name'
=>
self
::
TYPE_STRING
,
'numeric'
=>
self
::
TYPE_STRING
,
'numrange'
=>
self
::
TYPE_DECIMAL
,
'oid'
=>
self
::
TYPE_BIGINT
,
// should not be used. it's pg internal!
'path'
=>
self
::
TYPE_STRING
,
//'pg_node_tree' => self::TYPE_STRING,
'point'
=>
self
::
TYPE_STRING
,
'polygon'
=>
self
::
TYPE_STRING
,
//'refcursor' => self::TYPE_STRING,
//'regclass' => self::TYPE_STRING,
//'regconfig' => self::TYPE_STRING,
//'regdictionary' => self::TYPE_STRING,
//'regoper' => self::TYPE_STRING,
//'regoperator' => self::TYPE_STRING,
//'regproc' => self::TYPE_STRING,
//'regprocedure' => self::TYPE_STRING,
//'regtype' => self::TYPE_STRING,
//'reltime' => self::TYPE_STRING,
//'smgr' => self::TYPE_STRING,
'text'
=>
self
::
TYPE_TEXT
,
//'tid' => self::TYPE_STRING,
'time without time zone'
=>
self
::
TYPE_TIME
,
'timestamp without time zone'
=>
self
::
TYPE_TIMESTAMP
,
'timestamp with time zone'
=>
self
::
TYPE_TIMESTAMP
,
'time with time zone'
=>
self
::
TYPE_TIMESTAMP
,
//'tinterval' => self::TYPE_STRING,
//'tsquery' => self::TYPE_STRING,
//'tsrange' => self::TYPE_STRING,
//'tstzrange' => self::TYPE_STRING,
//'tsvector' => self::TYPE_STRING,
//'txid_snapshot' => self::TYPE_STRING,
'unknown'
=>
self
::
TYPE_STRING
,
'uuid'
=>
self
::
TYPE_STRING
,
'bit varying'
=>
self
::
TYPE_STRING
,
'character varying'
=>
self
::
TYPE_STRING
,
//'xid' => self::TYPE_STRING,
'xml'
=>
self
::
TYPE_STRING
);
/**
* Resolves the table name and schema name (if any).
* Resolves the table name and schema name (if any).
* @param TableSchema $table the table metadata object
* @param TableSchema $table the table metadata object
* @param string $name the table name
* @param string $name the table name
...
@@ -32,6 +112,9 @@ class Schema extends \yii\db\Schema {
...
@@ -32,6 +112,9 @@ class Schema extends \yii\db\Schema {
}
else
{
}
else
{
$table
->
name
=
$parts
[
0
];
$table
->
name
=
$parts
[
0
];
}
}
if
(
$table
->
schemaName
===
null
)
{
$table
->
schemaName
=
self
::
$DEFAULT_SCHEMA
;
}
}
}
/**
/**
...
@@ -52,11 +135,85 @@ class Schema extends \yii\db\Schema {
...
@@ -52,11 +135,85 @@ class Schema extends \yii\db\Schema {
public
function
loadTableSchema
(
$name
)
{
public
function
loadTableSchema
(
$name
)
{
$table
=
new
TableSchema
();
$table
=
new
TableSchema
();
$this
->
resolveTableNames
(
$table
,
$name
);
$this
->
resolveTableNames
(
$table
,
$name
);
$this
->
findPrimaryKeys
(
$table
);
if
(
$this
->
findColumns
(
$table
))
{
if
(
$this
->
findColumns
(
$table
))
{
$this
->
findForeignKeys
(
$table
);
$this
->
findForeignKeys
(
$table
);
return
$table
;
return
$table
;
}
}
}
}
/**
* Collects the metadata of table columns.
* @param TableSchema $table the table metadata
* @return boolean whether the table exists in the database
*/
protected
function
findColumns
(
$table
)
{
$dbname
=
$this
->
db
->
quoteValue
(
$this
->
db
->
pdo
->
getCurrentDatabase
());
$tableName
=
$this
->
db
->
quoteValue
(
$table
->
name
);
$schemaName
=
$this
->
db
->
quoteValue
(
$table
->
schemaName
);
$sql
=
<<<SQL
SELECT
current_database() as table_catalog,
d.nspname AS table_schema,
c.relname AS table_name,
a.attname AS column_name,
t.typname AS data_type,
a.attlen AS character_maximum_length,
pg_catalog.col_description(c.oid, a.attnum) AS column_comment,
a.atttypmod AS modifier,
a.attnotnull = false AS is_nullable,
CAST(pg_get_expr(ad.adbin, ad.adrelid) AS varchar) AS column_default,
coalesce(pg_get_expr(ad.adbin, ad.adrelid) ~ 'nextval',false) AS is_autoinc,
array_to_string((select array_agg(enumlabel) from pg_enum where enumtypid=a.atttypid)::varchar[],',') as enum_values
FROM
pg_class c
LEFT JOIN pg_attribute a ON a.attrelid = c.oid
LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
LEFT JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_namespace d ON d.oid = c.relnamespace
WHERE
a.attnum > 0
and c.relname = {$tableName}
and d.nspname = {$schemaName}
and current_database() = {$dbname}
ORDER BY
a.attnum;
SQL;
try
{
$columns
=
$this
->
db
->
createCommand
(
$sql
)
->
queryAll
();
}
catch
(
\Exception
$e
)
{
return
false
;
}
foreach
(
$columns
as
$column
)
{
$column
=
$this
->
loadColumnSchema
(
$column
);
if
(
$column
->
name
==
'numbers'
)
print_r
(
$column
);
}
die
();
}
/**
* Loads the column information into a [[ColumnSchema]] object.
* @param array $info column information
* @return ColumnSchema the column schema object
*/
protected
function
loadColumnSchema
(
$info
)
{
$column
=
new
ColumnSchema
();
$column
->
allowNull
=
$info
[
'is_nullable'
];
$column
->
autoIncrement
=
$info
[
'is_autoinc'
];
$column
->
comment
=
$info
[
'column_comment'
];
$column
->
dbType
=
$info
[
'data_type'
];
$column
->
defaultValue
=
$info
[
'column_default'
];
$column
->
enumValues
=
explode
(
','
,
str_replace
(
array
(
"''"
),
array
(
"'"
),
$info
[
'enum_values'
]));
//$column->isPrimaryKey
$column
->
name
=
$info
[
'column_name'
];
//$column->phpType
//$column->precision
//$column->scale
//$column->size;
//$column->type
//$column->unsigned
return
$column
;
}
}
}
\ No newline at end of file
tests/unit/data/postgres.sql
View file @
103621ad
...
@@ -11,14 +11,26 @@ DROP TABLE IF EXISTS tbl_category CASCADE;
...
@@ -11,14 +11,26 @@ DROP TABLE IF EXISTS tbl_category CASCADE;
DROP
TABLE
IF
EXISTS
tbl_customer
CASCADE
;
DROP
TABLE
IF
EXISTS
tbl_customer
CASCADE
;
DROP
TABLE
IF
EXISTS
tbl_type
CASCADE
;
DROP
TABLE
IF
EXISTS
tbl_type
CASCADE
;
drop
type
if
exists
fullname
cascade
;
create
type
fullname
as
(
firstname
varchar
,
lastname
varchar
);
drop
type
if
exists
mood
cascade
;
create
type
mood
as
enum
(
'sad'
,
'ok'
,
'happy'
,
E
'own
\'
s'
,
E
'
\"
quoted
\"
'
);
CREATE
TABLE
tbl_customer
(
CREATE
TABLE
tbl_customer
(
id
serial
not
null
primary
key
,
id
serial
not
null
primary
key
,
email
varchar
(
128
)
NOT
NULL
,
email
varchar
(
128
)
NOT
NULL
,
name
varchar
(
128
)
NOT
NULL
,
name
varchar
(
128
)
NOT
NULL
,
address
text
,
address
text
,
status
integer
DEFAULT
0
status
integer
DEFAULT
0
,
fullname
fullname
,
mood
mood
,
numbers
integer
[]
);
);
comment
on
column
public
.
tbl_customer
.
email
is
'someone@example.com'
;
CREATE
TABLE
tbl_category
(
CREATE
TABLE
tbl_category
(
id
serial
not
null
primary
key
,
id
serial
not
null
primary
key
,
name
varchar
(
128
)
NOT
NULL
name
varchar
(
128
)
NOT
NULL
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment