From 1cabb6240534abf49629fabd22fa893a3c564653 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Fri, 13 Aug 2004 18:59:00 +0000 Subject: [PATCH] new schema_proc class seems to work now --- .../inc/adodb/datadict/datadict-mssql.inc.php | 4 +- .../adodb/datadict/datadict-postgres.inc.php | 2 +- .../inc/adodb/datadict/datadict-sapdb.inc.php | 2 +- .../inc/adodb/drivers/adodb-sapdb.inc.php | 27 +- phpgwapi/inc/class.db.inc.php | 2 +- phpgwapi/inc/class.interserver.inc.php | 4 +- phpgwapi/inc/class.setup_process.inc.php | 6 + phpgwapi/inc/common_functions.inc.php | 6 +- phpgwapi/tests/schema_proc.php | 258 ++++++++++++++++-- 9 files changed, 269 insertions(+), 42 deletions(-) diff --git a/phpgwapi/inc/adodb/datadict/datadict-mssql.inc.php b/phpgwapi/inc/adodb/datadict/datadict-mssql.inc.php index 114fd0f4b6..0d10118f3c 100644 --- a/phpgwapi/inc/adodb/datadict/datadict-mssql.inc.php +++ b/phpgwapi/inc/adodb/datadict/datadict-mssql.inc.php @@ -17,8 +17,8 @@ class ADODB2_mssql extends ADODB_DataDict { var $databaseType = 'mssql'; var $dropIndex = 'DROP INDEX %2$s.%1$s'; - var $renameTable = "EXEC sp_rename '%1','%2'"; - var $renameColumn = "EXEC sp_rename '%1.%2','%3'"; + var $renameTable = "EXEC sp_rename '%s','%s'"; + var $renameColumn = "EXEC sp_rename '%s.%s','%s'"; function MetaType($t,$len=-1,$fieldobj=false) { diff --git a/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php b/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php index 93c2735d69..14e2aba659 100644 --- a/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php +++ b/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php @@ -175,7 +175,7 @@ class ADODB2_postgres extends ADODB_DataDict { foreach($this->MetaColumns($tabname) as $fld) { if (!$dropflds || !in_array($fld->name,$dropflds)) { $copyflds[] = $fld->name; - // identify the sequenze name and the fld its on + // identify the sequence name and the fld its on if ($fld->primary_key && $fld->has_default && preg_match("/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) { $seq_name = $matches[1]; diff --git a/phpgwapi/inc/adodb/datadict/datadict-sapdb.inc.php b/phpgwapi/inc/adodb/datadict/datadict-sapdb.inc.php index bac91a6fdd..b21085f4e9 100644 --- a/phpgwapi/inc/adodb/datadict/datadict-sapdb.inc.php +++ b/phpgwapi/inc/adodb/datadict/datadict-sapdb.inc.php @@ -18,7 +18,7 @@ class ADODB2_sapdb extends ADODB_DataDict { var $databaseType = 'sapdb'; var $seqField = false; - var $renameCol = 'RENAME COLUMN %s.%s TO %s'; + var $renameColumn = 'RENAME COLUMN %s.%s TO %s'; function ActualType($meta) { diff --git a/phpgwapi/inc/adodb/drivers/adodb-sapdb.inc.php b/phpgwapi/inc/adodb/drivers/adodb-sapdb.inc.php index 19f93df754..0bca08de20 100644 --- a/phpgwapi/inc/adodb/drivers/adodb-sapdb.inc.php +++ b/phpgwapi/inc/adodb/drivers/adodb-sapdb.inc.php @@ -36,16 +36,19 @@ class ADODB_SAPDB extends ADODB_odbc { $this->ADODB_odbc(); } + function ServerInfo() + { + $info = ADODB_odbc::ServerInfo(); + if (!$info['version'] && preg_match('/([0-9.]+)/',$info['description'],$matches)) { + $info['version'] = $matches[1]; + } + return $info; + } + function &MetaIndexes ($table, $primary = FALSE) { - if ($primary) { - return array( - 'SYSPRIMARYKEYINDEX' => array( - 'unique' => True, // by definition - 'columns' => $this->MetaPrimaryKeys($table), - )); - } $table = $this->Quote(strtoupper($table)); + $sql = "SELECT INDEXNAME,TYPE,COLUMNNAME FROM INDEXCOLUMNS ". " WHERE TABLENAME=$table". " ORDER BY INDEXNAME,COLUMNNO"; @@ -71,6 +74,16 @@ class ADODB_SAPDB extends ADODB_odbc { $indexes[$row[0]]['unique'] = $row[1] == 'UNIQUE'; $indexes[$row[0]]['columns'][] = $row[2]; } + if ($primary) { + $columns = array(); + foreach($this->GetAll("SELECT columnname FROM COLUMNS WHERE tablename=$table AND mode='KEY' ORDER BY pos") as $row) { + $columns[] = $row['COLUMNNAME']; + } + $indexes['SYSPRIMARYKEYINDEX'] = array( + 'unique' => True, // by definition + 'columns' => $columns, + ); + } return $indexes; } diff --git a/phpgwapi/inc/class.db.inc.php b/phpgwapi/inc/class.db.inc.php index 2c01291679..d2bc0bf541 100644 --- a/phpgwapi/inc/class.db.inc.php +++ b/phpgwapi/inc/class.db.inc.php @@ -1116,7 +1116,7 @@ } /** - * Insert a row of data into a table, all data is quoted according to it's type + * Insert a row of data into a table or updates it if $where is given, all data is quoted according to it's type * * @author RalfBeckeroutdoor-training.de * diff --git a/phpgwapi/inc/class.interserver.inc.php b/phpgwapi/inc/class.interserver.inc.php index 356aa6a4d8..571ce1b682 100644 --- a/phpgwapi/inc/class.interserver.inc.php +++ b/phpgwapi/inc/class.interserver.inc.php @@ -191,7 +191,7 @@ $this->debug("
" . htmlentities($f->serialize()) . "
\n",$debug); $c = CreateObject('phpgwapi.xmlrpc_client',$uri, $hostpart, 443); $c->setCredentials($this->sessionid,$this->kp3); - $c->setDebug(0); + $c->setDebug($debug); $r = $c->send($f,0,'https'); if (!$r) { @@ -244,7 +244,7 @@ $c = CreateObject('phpgwapi.xmlrpc_client',$uri, $hostpart, 80); $c->setCredentials($this->sessionid,$this->kp3); // _debug_array($c); - $c->setDebug(0); + $c->setDebug($debug); $r = $c->send($f); if (!$r) { diff --git a/phpgwapi/inc/class.setup_process.inc.php b/phpgwapi/inc/class.setup_process.inc.php index fe3ebfee3d..079c5ecdab 100644 --- a/phpgwapi/inc/class.setup_process.inc.php +++ b/phpgwapi/inc/class.setup_process.inc.php @@ -97,6 +97,12 @@ /* stuff the rest of the apps, but only those with available upgrades */ while(list($key,$value) = @each($setup_info)) { + if (isset($value['only_db']) && ( + is_array($value['only_db']) && !in_array($GLOBALS['phpgw_setup']->db->Type,$value['only_db']) || + !is_array($value['only_db']) && $GLOBALS['phpgw_setup']->db->Type != $value['only_db'])) + { + continue; // app does not support this db-type, dont try installing it + } if(($value['name'] != 'phpgwapi') && ($value['status'] == 'U')) { if(($passed[$value['name']]['status'] != 'F') && ($passed[$value['name']]['status'] != 'C')) diff --git a/phpgwapi/inc/common_functions.inc.php b/phpgwapi/inc/common_functions.inc.php index 53bbdf9e14..9c2a424ed4 100755 --- a/phpgwapi/inc/common_functions.inc.php +++ b/phpgwapi/inc/common_functions.inc.php @@ -696,7 +696,7 @@ @param $classname name of class @param $p1-$p16 class parameters (all optional) */ - function CreateObject($class, + function &CreateObject($class, $p1='_UNDEF_',$p2='_UNDEF_',$p3='_UNDEF_',$p4='_UNDEF_', $p5='_UNDEF_',$p6='_UNDEF_',$p7='_UNDEF_',$p8='_UNDEF_', $p9='_UNDEF_',$p10='_UNDEF_',$p11='_UNDEF_',$p12='_UNDEF_', @@ -759,6 +759,10 @@ $code = substr($code,0,-1) . ');'; eval($code); } + if (!is_object($obj)) + { + function_backtrace(1); + } /* error_reporting(E_ERROR | E_WARNING | E_PARSE); */ return $obj; } diff --git a/phpgwapi/tests/schema_proc.php b/phpgwapi/tests/schema_proc.php index 497e4c0c50..ed83059867 100755 --- a/phpgwapi/tests/schema_proc.php +++ b/phpgwapi/tests/schema_proc.php @@ -62,72 +62,276 @@ ), 'pk' => array('test_auto'), 'fk' => array(), - 'ix' => array('test_varchar',array('test_text','options'=>array('mysql'=>'FULLTEXT','maxdb'=>false,'pgsql'=>false))), + 'ix' => array('test_varchar',array('test_text','options'=>array('mysql'=>'FULLTEXT','sapdb'=>false,'maxdb'=>false,'pgsql'=>false,'mssql'=>false))), 'uc' => array('test_char') ), ); - echo "Creating table(s):\n"; - $meta_tables = $adodb->MetaTables(); - foreach($test_tables as $name => $definition) + // droping test-tables, if they are there from a previous failed run + foreach($adodb->MetaTables() as $table) { - // droping the tables, if they exist from a previous run - if (in_array($name,$meta_tables) || in_array(strtoupper($name),$meta_tables)) + $table = strtolower($table); + if (strstr($table,'schema_proc')) { - $schema_proc->DropTable($name); + $aSql = $schema_proc->dict->DropTableSQL($table); + $schema_proc->ExecuteSqlArray($aSql,1,"DropTableSQL('%1') = %2",$table,$aSql); } - $schema_proc->CreateTable($name,$definition); } - - echo "\nReading back the tables via MetaColumns:\n"; + + echo "Creating table(s):\n"; foreach($test_tables as $name => $definition) { + echo "$name:\n"; + $schema_proc->CreateTable($name,$definition); + $columns = $adodb->MetaColumns($name); if (!$columns || count($columns) <= 0) { - echo "\n\n!!! Table '$name' has NOT been created !!!\n\n"; + die("\n\n!!! Table '$name' has NOT been created !!!\n\n"); } else { - print_r($columns); - print_r($adodb->MetaIndexes($name)); - } + // check if all columns are there + foreach($definition['fd'] as $column => $data) + { + check_column($column,$columns); + if (!isset($columns[$column]) && !isset($columns[strtoupper($column)])) + { + print_r($columns); + die ("\n\n!!! Column '$column' is missing !!!\n\n"); + } + } + // check if all indexes are there + $indexes = $adodb->MetaIndexes($name,true); + if ($indexes !== False) + { + foreach(array('ix','uc') as $kind) + { + foreach($definition[$kind] as $key => $idx) + { + check_index($idx,$kind=='uc',$indexes); + } + } + if (count($definition['pk'])) check_index($definition['pk'],True,$indexes); + } + } + echo $indexes !== False ? "==> SUCCESS\n" : "==> unchecked\n"; } echo "Inserting some content:\n"; $adodb->Execute("INSERT INTO schema_proc_test (test_int4,test_varchar,test_char) VALUES (1,'Hallo Ralf','0123456789')"); $adodb->Execute("INSERT INTO schema_proc_test (test_int4,test_varchar,test_char) VALUES (2,'Hallo wer noch?','9876543210')"); - + check_content($adodb->GetAll("SELECT * FROM schema_proc_test"),array( + array('test_auto' => 1, 'test_int4' => 1, 'test_varchar' => 'Hallo Ralf','test_char' => '0123456789'), + array('test_auto' => 2, 'test_int4' => 2, 'test_varchar' => 'Hallo wer noch?','test_char' => '9876543210'), + )); + echo "==> SUCCESS\n"; + echo "Droping column test_blob:\n"; $new_table_def = $test_tables['schema_proc_test']; unset($new_table_def['fd']['test_blob']); $schema_proc->DropColumn('schema_proc_test',$new_table_def,'test_blob'); + check_column('test_blob',$adodb->MetaColumns('schema_proc_test'),False); + echo "==> SUCCESS\n"; echo "Altering column test_char to varchar(32):\n"; $schema_proc->AlterColumn('schema_proc_test','test_char',array('type' => 'varchar','precision' => 32)); + check_column_type('test_char','varchar',32,$adodb->MetaColumns('schema_proc_test')); + echo "==> SUCCESS\n"; echo "Adding column test_bool bool:\n"; $schema_proc->AddColumn('schema_proc_test','test_bool',array('type' => 'bool')); + check_column('test_bool',$adodb->MetaColumns('schema_proc_test')); + echo "==> SUCCESS\n"; echo "Renaming column test_timestamp to test_time:\n"; $schema_proc->RenameColumn('schema_proc_test','test_timestamp','test_time'); + check_column('test_timestamp',$adodb->MetaColumns('schema_proc_test'),false); + check_column('test_time',$adodb->MetaColumns('schema_proc_test')); + echo "==> SUCCESS\n"; echo "Renaming table schema_proc_test to schema_proc_renamed:\n"; $schema_proc->RenameTable('schema_proc_test','schema_proc_renamed'); + $tables = $adodb->MetaTables(); + check_table('schema_proc_test',$tables,False); + check_table('schema_proc_renamed',$tables); + echo "==> SUCCESS\n"; - print_r($adodb->MetaColumns('schema_proc_renamed')); - print_r($adodb->MetaIndexes('schema_proc_renamed')); + echo "Renaming column (with index) test_varchar to test_varchar_renamed:\n"; + $schema_proc->RenameColumn('schema_proc_renamed','test_varchar','test_varchar_renamed'); + $columns = $adodb->MetaColumns('schema_proc_renamed'); + check_column('test_varchar',$columns,False); + check_column('test_varchar_renamed',$columns); + $indexes = $adodb->MetaIndexes('schema_proc_renamed'); + if ($indexes !== False) + { + check_index('test_varchar',False,$indexes,False); + check_index('test_varchar_renamed',False,$indexes); + } + echo $indexes !== False ? "==> SUCCESS\n" : "==> unchecked\n"; - echo "Inserting some more content:\n"; - $db->query("INSERT INTO schema_proc_renamed (test_int4,test_varchar,test_char) VALUES (10,'Hallo Hallo Hallo ...','12345678901234567890123456789012')"); + echo "Droping index from renamed column test_varchar_renamed:\n"; + $schema_proc->DropIndex('schema_proc_renamed',array('test_varchar_renamed')); + $indexes = $adodb->MetaIndexes('schema_proc_renamed'); + if ($indexes !== False) check_index('test_varchar_renamed',False,$indexes,False); + echo $indexes !== False ? "==> SUCCESS\n" : "==> unchecked\n"; + + //print_r($adodb->MetaColumns('schema_proc_renamed')); + //print_r($adodb->MetaIndexes('schema_proc_renamed')); + + echo "Inserting some more content\n"; + $db->query("INSERT INTO schema_proc_renamed (test_int4,test_varchar_renamed,test_char) VALUES (10,'Hallo Hallo Hallo ...','12345678901234567890123456789012')"); + check_content($adodb->GetAll("SELECT * FROM schema_proc_renamed"),array( + array('test_auto' => 1, 'test_int4' => 1, 'test_varchar_renamed' => 'Hallo Ralf','test_char' => '0123456789'), + array('test_auto' => 2, 'test_int4' => 2, 'test_varchar_renamed' => 'Hallo wer noch?','test_char' => '9876543210'), + array('test_auto' => 3, 'test_int4' => 10, 'test_varchar_renamed' => 'Hallo Hallo Hallo ...','test_char' => '12345678901234567890123456789012'), + )); + echo "==> SUCCESS\n"; - echo "Reading back the content:\n"; - $all = $adodb->GetAll("SELECT * FROM schema_proc_renamed"); - print_r($all); + //echo "Reading back the content:\n"; + //$all = $adodb->GetAll("SELECT * FROM schema_proc_renamed"); + //print_r($all); - $schema_proc->RenameTable('schema_proc_renamed','schema_proc_test'); // so we can drop it under its original name - - echo "\nDroping the test-tables again:\n"; - if (!$schema_proc->DropAllTables($test_tables)) echo "!!!Failed !!!\n"; - + echo "\nDroping the test-tables again\n"; + foreach($adodb->MetaTables() as $table) + { + $table = strtolower($table); + if (strstr($table,'schema_proc')) + { + $aSql = $schema_proc->dict->DropTableSQL($table); + $schema_proc->ExecuteSqlArray($aSql,1,"DropTableSQL('%1') = %2",$table,$aSql); + } + } + echo "\n********************\n"; + echo "*** FULL SUCCESS ***\n"; + echo "********************\n"; echo "\nbye ...\n"; + + + /** + * Checks if table $table exists or not, die's with an error-message if the check went wrong + * + * @param string $table table-name + * @param array $tables array of table-names from call to MetaTables() + * @param boolean $existence=true should we check for existence or none-existence, default existence + */ + function check_table($table,$tables,$existence=True) + { + $exist = in_array($table,$tables) || in_array(strtoupper($table),$tables); + + if ($exist != $existence) + { + print_r($tables); + die ("\n\n!!! Table '$table' is ".($existence ? 'missing' : 'still there')." !!!\n\n"); + } + } + + /** + * Checks if $column exists or not, die's with an error-message if the check went wrong + * + * @param string $column column-name + * @param array $columns array of adodb field objects from MetaColumns($table) + * @param boolean $existence=true should we check for existence or none-existence, default existence + */ + function check_column($column,$columns,$existence=True) + { + $exist = isset($columns[$column]) || isset($columns[strtoupper($column)]); + + if ($exist != $existence) + { + print_r($columns); + die ("\n\n!!! Column '$column' is ".($existence ? 'missing' : 'still there')." !!!\n\n"); + } + } + /** + * Checks the type of a column + * + * @param string $column column-name + * @param string $type column-type as the DB uses it, no eGW type !!! + * @param int $precision precision + * @param array $columns array of adodb field objects from MetaColumns($table) + */ + function check_column_type($column,$type,$precision,$columns) + { + static $alternate_types = array( + 'varchar' => array('C'), + 'int' => array('I'), + ); + + $data = isset($columns[$column]) ? $columns[$column] : $columns[strtoupper($column)]; + + if (!is_object($data)) + { + print_r($columns); + die ("\n\n!!! Column '$column' does NOT exist !!!\n\n"); + } + if ($data->type != $type && !in_array($data->type,$alternate_types[$type])) + { + print_r($columns); + die ("\n\n!!! Column '$column' is NOT of type '$type', but '$data->type' !!!\n\n"); + } + if ($precision && $data->max_length != $precision) + { + print_r($columns); + die ("\n\n!!! Precision of column '$column' is NOT $precision, but $data->precision !!!\n\n"); + } + } + + /** + * Checks if $idx exists or not, die's with an error-message if the check went wrong + * + * @param array $columns array of strings with column-names of that index + * @param boolean $unique unique index or not + * @param array $indexes array of index-describtions from call to MetaIndexes($table) + * @param boolean $existence=true should we check for existence or none-existence, default existence + */ + function check_index($columns,$unique,$indexes,$existence=True) + { + if (!is_array($columns)) $columns = array($columns); + $existence = $existence && $columns['options'][$GLOBALS['db']->Type] !== False; + unset($columns['options']); + + $exist = False; + foreach($indexes as $idx_data) + { + if (implode(':',$columns) == strtolower(implode(':',$idx_data['columns']))) + { + $exist = true; + break; + } + } + if ($exist != $existence) + { + print_r($indexes); + die ("\n\n!!! Index (".implode(', ',$columns).") is ".($existence ? 'missing' : 'still there')." !!!\n\n"); + } + if ($existence && $unique != !!$idx_data['unique']) + { + print_r($indexes); + die ("\n\n!!! Index (".implode(', ',$columns).") is ".($unique ? 'NOT ' : '')."unique !!!\n\n"); + } + } + + /** + * Checks the content written to the table + * + * @param array $is content read from the database via GetAll() + * @param array $should content against which we test + * @param boolean $return_false=false return false if the check fails or die with an error-msg, default die + */ + function check_content($is,$should,$return_false=false) + { + foreach($should as $key => $val) + { + if (!isset($is[$key]) && isset($is[strtoupper($key)])) $key = strtoupper($key); + if (is_array($val) && !check_content($is[$key],$val,True) || !is_array($val) && $is[$key] != $val) + { + echo "key='$key', is="; print_r($is[$key]); echo ", should="; print_r($val); echo "\n"; + if ($return_false) return False; + + print_r($is); + die("\n\n!!! Content read back from table is not as expected !!!\n\n"); + } + } + return True; + }