Skip to content

Commit

Permalink
Merge pull request #53 from ghousseyn/alpha
Browse files Browse the repository at this point in the history
Collection updated
  • Loading branch information
ghousseyn committed Aug 20, 2014
2 parents c308728 + c0f3e1d commit e4eebb7
Show file tree
Hide file tree
Showing 4 changed files with 342 additions and 1 deletion.
6 changes: 6 additions & 0 deletions library/oosql/collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,17 @@ public function countWhere($property, $value)
*/
public function removeWhere($property, $value)
{
$results = array();
foreach($this->objects as $key => $obj){
if($obj->{$property} === $value){
$this->deletedObjects[] = $this->objects[$key];
$results[] = $this->objects[$key];
unset($this->objects[$key]);
$this->numObjects--;
}
}
$this->objects = array_values($this->objects);
return $results;
}

public function restoreWhere($property, $value)
Expand All @@ -141,6 +144,9 @@ public function getLast()

public function pop()
{
if($this->count() == 0){
return false;
}
$element = $this->objects[$this->numObjects - 1];
$this->deletedObjects[] = $element;
unset($this->objects[$this->numObjects - 1]);
Expand Down
128 changes: 128 additions & 0 deletions library/oosql/mysql.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php
namespace Phiber\oosql;
require 'oogen.php';

class mysql extends oogen
{

protected $queries = array('tables' => 'SHOW TABLES',
'columns' => 'SHOW COLUMNS FROM',
'create' => 'show create table');


protected function createProps($fields,$tname,$cols)
{
$count = 0;
$rel = false;

foreach($cols as $col){

if(isset($col['constraints'])){

$cnt = count($fields[$tname]);
for($i = 0; $i < $cnt; $i++){
foreach($fields[$tname][$i] as $key => $val){

if(! empty($val) && is_string($val) && isset($col['constraints'][$val])){
$this->foreign[$tname][$val] = $col['constraints'][$val];

$this->belongsTo[$tname][] = $col['constraints'][$val][1];

$this->hasMany[$col['constraints'][$val][1]][] = trim($col['constraints'][$val][0]).'.'.$tname.'.'.$val;



}
}
}
}

if( $col['Key'] == 'PRI'){
$this->primary[$tname][] = $col['Field'];
}



}
foreach($cols as $col){

if(isset($col['Key'])){

if($col['Key'] == 'UNI'){
$this->unique[$tname][] = $col['Field'];
if(isset($this->foreign[$tname][trim($col['Field'])])){
$l_field = trim($this->foreign[$tname][$col['Field']][0]);
$f_table = trim($this->foreign[$tname][$col['Field']][1]);
$this->hasOne[$f_table][] = $l_field.'.'.$tname.'.'.$col['Field'];
$tkey = array_search($l_field, $f_table);
unset($this->hasMany[$f_table][$tkey]);

}
}
}
}

}

protected function analyze($tbls)
{
foreach($tbls as &$tbl){

$table = array_pop($tbl);

print "Analyzing $table physical columns ..." . PHP_EOL;

$query = $this->queries['columns'] . ' ' . $table;

$collection = $this->getCollection($query);

if(!$collection){

foreach($this->errors as $error){
print implode('|', $error) . PHP_EOL;
}
return false;
}
foreach($collection as $columns){
$fields[$table][] = (array) $columns;
}

print "Analyzing $table DDL ..." . PHP_EOL;

$ddl = $this->getCollection($this->queries['create'] . ' `' . $table . '`');

if(!$ddl){

foreach($this->errors as $error){
print implode('|', $error) . PHP_EOL;
}
return false;
}

$ks = array();
foreach($ddl as $ex){
$ks[] = (array) $ex;
}

$create = $ks[0]['Create Table'];

$keys = explode(',', $create);
$kcount = count($keys);
while(substr(trim($keys[$kcount - 1]), 0, 10) === 'CONSTRAINT'){
// @Todo Composite key constraints are not handled correctly
$key = array_pop($keys);
$parts = explode(' ', trim($key));
$constraint = trim($parts[1], '`');
$fkey = trim($parts[4], '()`');
$reftable = trim($parts[6], '`');
$reffield = trim($parts[7], '()`');
$reffield = str_replace(array(')','`'),array('',''),$reffield);
print "Found constraint $constraint ..." . PHP_EOL;
$fields[$table][]['constraints'][$fkey] = array($reffield, $reftable);
unset($keys[$kcount - 1]);
$kcount--;
}
}
return $fields;
}
}
2 changes: 1 addition & 1 deletion library/oosql/oogen.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ protected function createBody($table)
}
$this->text .= ' );' . PHP_EOL . ' }' . PHP_EOL;
}else{
$this->text .= ' public function getPrimaryValue($key=null)' . PHP_EOL . ' {' . PHP_EOL . ' if(null === $key){' . PHP_EOL . ' return array("' . implode("", $primKey) . '" => $this->' . implode("", $primKey) . ');' . PHP_EOL . ' }' . PHP_EOL . ' $pri = $this->getPrimary();' . PHP_EOL . ' if(in_array($key,$pri)){' . PHP_EOL . ' return $this->{$pri[$key]};' . PHP_EOL . ' }' . PHP_EOL . ' }' . PHP_EOL;
$this->text .= ' public function getPrimaryValue($key=null)' . PHP_EOL . ' {' . PHP_EOL . ' if(null === $key){' . PHP_EOL . ' return array("' . implode("", $primKey) . '" => $this->' . implode("", $primKey) . ');' . PHP_EOL . ' }' . PHP_EOL . ' $pri = $this->getPrimary();' . PHP_EOL . ' if(in_array($key,$pri)){' . PHP_EOL . ' return $this->{$key};' . PHP_EOL . ' }' . PHP_EOL . ' }' . PHP_EOL;

}
// unset($primary);
Expand Down
207 changes: 207 additions & 0 deletions library/oosql/pgsql.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
<?php
namespace Phiber\oosql;
require 'oogen.php';

class pgsql extends oogen
{

protected $queries = array('tables' => "SELECT table_name FROM information_schema.tables where table_schema = 'public'",
'columns' => "SELECT column_name AS Field
FROM information_schema.columns where table_schema = 'public' and table_name='<table>'",
'schema' => "SELECT distinct table_schema FROM information_schema.tables where table_schema not in ('pg_catalog','information_schema')",
'constraint'=> "SELECT
pc.conname,
pg_catalog.pg_get_constraintdef(pc.oid, true) AS consrc,
pc.contype
FROM
pg_catalog.pg_constraint pc
WHERE
pc.conrelid = (SELECT oid FROM pg_catalog.pg_class WHERE relname='<table>'
AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace
WHERE nspname='public'))
ORDER BY
1");

protected $seq = array();


protected function createProps($fields,$tname,$cols)
{
$count = 0;
foreach($cols as $col){

if(isset($col['constraints'])){

$cnt = count($fields[$tname]);
for($i = 0; $i < $cnt; $i++){
foreach($fields[$tname][$i] as $key => $val){

if(! empty($val) && is_string($val) && isset($col['constraints'][$val])){
$this->foreign[$val] = $col['constraints'][$val];
}
}
}
}


if(! isset($col['Field']) || strlen($col['Field']) == 0){
continue;
}else{
$seq = $tname.'_'.$col['Field'].'_seq';

if(in_array($seq,$this->seq)){
$this->ai = $col['Field'];
}
$this->text .= ' public $' . $col['Field'] . ';' . PHP_EOL;
}
$count++;
}
}

protected function analyze($tbls)
{
foreach($tbls as &$tbl){

$table = array_pop($tbl);

$tables[] = array('schemaname'=>'public','tablename'=>$table);

print "Analyzing $table physical columns ..." . PHP_EOL;

$query = str_replace('<table>',$table,$this->queries['columns']);

$collection = $this->getCollection($query);

if(!$collection){

foreach($this->errors as $error){
print implode('|', $error) . PHP_EOL;
}
return false;
}
foreach($collection as $columns){
$fields[$table][]['Field'] = $columns['field'];
}

print "Analyzing $table DDL ..." . PHP_EOL;

$constraints = $this->getCollection(str_replace('<table>',$table,$this->queries['constraint']));

//var_dump($constraints);

$ks = array();
if($constraints){
foreach($constraints as $ex){

$string = $ex['consrc'];
$parts = explode('REFERENCES',$string);

$local = explode(' ',$parts[0]);

$fkey = str_replace(' ','_',trim($local[2],'()'));
if($local[0] != 'FOREIGN'){

if(trim($local[0]) == 'PRIMARY'){

$this->primary[$table][] = $fkey;
}
continue;
}
$ref = explode('(',$parts[1]);
$reftable = str_replace(' ','_',trim($ref[0]));
$reffield = str_replace(' ','_',rtrim($ref[1],')'));
print 'Found constraint '.$ex['conname'].' ...'.PHP_EOL;
$fields[$table][]['constraints'][$fkey] = array($reffield, $reftable);
}
}



}

var_dump($this->getLinkingKeys($tables));
return $fields;
}
public function getLinkingKeys($tables) {
if (!is_array($tables)) return -1;
$arr = array();
$tables_list = "'{$tables[0]['tablename']}'";
$schema_list = "'{$tables[0]['schemaname']}'";
$schema_tables_list = "'{$tables[0]['schemaname']}.{$tables[0]['tablename']}'";

for ($i = 1; $i < sizeof($tables); $i++) {

$tables_list .= ", '{$tables[$i]['tablename']}'";
$schema_list .= ", '{$tables[$i]['schemaname']}'";
$schema_tables_list .= ", '{$tables[$i]['schemaname']}.{$tables[$i]['tablename']}'";
}

$maxDimension = 1;

$sql = "
SELECT DISTINCT
array_dims(pc.conkey) AS arr_dim,
pgc1.relname AS p_table
FROM
pg_catalog.pg_constraint AS pc,
pg_catalog.pg_class AS pgc1
WHERE
pc.contype = 'f'
AND (pc.conrelid = pgc1.relfilenode OR pc.confrelid = pgc1.relfilenode)
AND pgc1.relname IN ($tables_list)
";

//parse our output to find the highest dimension of foreign keys since pc.conkey is stored in an array
$rs = $this->getCollection($sql);
foreach ($rs as $line) {
$arr[$line['p_table']]=$line['arr_dim'];
$arrData = explode(':', $line['arr_dim']);
$tmpDimension = intval(substr($arrData[1], 0, strlen($arrData[1] - 1)));
$maxDimension = $tmpDimension > $maxDimension ? $tmpDimension : $maxDimension;
}

//we know the highest index for foreign keys that conkey goes up to, expand for us in an IN query
$cons_str = '( (pfield.attnum = conkey[1] AND cfield.attnum = confkey[1]) ';
for ($i = 2; $i <= $maxDimension; $i++) {
$cons_str .= "OR (pfield.attnum = conkey[{$i}] AND cfield.attnum = confkey[{$i}]) ";
}
$cons_str .= ') ';

$sql = "
SELECT
pgc1.relname AS p_table,
pgc2.relname AS f_table,
pfield.attname AS p_field,
cfield.attname AS f_field,
pgns1.nspname AS p_schema,
pgns2.nspname AS f_schema
FROM
pg_catalog.pg_constraint AS pc,
pg_catalog.pg_class AS pgc1,
pg_catalog.pg_class AS pgc2,
pg_catalog.pg_attribute AS pfield,
pg_catalog.pg_attribute AS cfield,
(SELECT oid AS ns_id, nspname FROM pg_catalog.pg_namespace WHERE nspname IN ($schema_list) ) AS pgns1,
(SELECT oid AS ns_id, nspname FROM pg_catalog.pg_namespace WHERE nspname IN ($schema_list) ) AS pgns2
WHERE
pc.contype = 'f'
AND pgc1.relnamespace = pgns1.ns_id
AND pgc2.relnamespace = pgns2.ns_id
AND pc.conrelid = pgc1.relfilenode
AND pc.confrelid = pgc2.relfilenode
AND pfield.attrelid = pc.conrelid
AND cfield.attrelid = pc.confrelid
AND $cons_str
AND pgns1.nspname || '.' || pgc1.relname IN ($schema_tables_list)
AND pgns2.nspname || '.' || pgc2.relname IN ($schema_tables_list)
";

foreach($this->getCollection($sql) as $key => $res){
$res['rel'] = $arr[$res['p_table']];
$newArr[$res['p_table']] = $res;

}
return $newArr;
}
}

0 comments on commit e4eebb7

Please sign in to comment.