diff --git a/phpgwapi/inc/class.db_pgsql.inc.php b/phpgwapi/inc/class.db_pgsql.inc.php index faba086b60..b554228f59 100644 --- a/phpgwapi/inc/class.db_pgsql.inc.php +++ b/phpgwapi/inc/class.db_pgsql.inc.php @@ -15,377 +15,422 @@ /* $Id$ */ -class db { - var $Host = ""; - var $Database = ""; - var $User = ""; - var $Password = ""; - - var $use_pconnect = False; - var $auto_stripslashes = False; - - var $Halt_On_Error = "yes"; ## "yes" (halt with message), "no" (ignore errors quietly), "report" (ignore errror, but spit a warning) - - var $Link_ID = 0; - var $Query_ID = 0; - var $Record = array(); - var $Row = 0; - - var $Seq_Table = "db_sequence"; - - var $Errno = 0; - var $Error = ""; - - var $Auto_Free = 0; # Set this to 1 for automatic pg_freeresult on - # last record. - - function ifadd($add, $me) { - if("" != $add) return " ".$me.$add; - } - - /* public: constructor */ - function db($query = "") { - $this->query($query); - } - - function connect() { - if ( 0 == $this->Link_ID ) { - $cstr = "dbname=".$this->Database. - $this->ifadd($this->Host, "host="). - $this->ifadd($this->Port, "port="). - $this->ifadd($this->User, "user="). - $this->ifadd($this->Password, "password="); - if ($this->use_pconnect) - $this->Link_ID=pg_pconnect($cstr); - else - $this->Link_ID=pg_connect($cstr); - if (!$this->Link_ID) { - $this->halt("Link-ID == false, pconnect failed"); - } - } - } - - function limit($start) - { - global $phpgw_info; - - echo 'Warning: limit() is no longer used, use limit_query()'; - - if ($start == 0) { - $s = "limit " . $phpgw_info["user"]["preferences"]["common"]["maxmatchs"]; - } else { - $s = "limit " . $phpgw_info["user"]["preferences"]["common"]["maxmatchs"] . ",$start"; - } - return $s; - } - - // This only affects systems not using persistant connections - function disconnect() - { - return @pg_close($this->Link_ID); - } - - // I added the line and file section so we can have better error reporting. (jengo) - function query($Query_String, $line = "", $file = "") { - /* No empty queries, please, since PHP4 chokes on them. */ - if ($Query_String == "") - /* The empty query string is passed on from the constructor, - * when calling the class without a query, e.g. in situations - * like these: '$db = new db_Subclass;' - */ - return 0; - - $this->connect(); - -# printf("
Debug: query = %s
\n", $Query_String); - - $this->Query_ID = pg_Exec($this->Link_ID, $Query_String); - $this->Row = 0; - - $this->Error = pg_ErrorMessage($this->Link_ID); - $this->Errno = ($this->Error == "")?0:1; - if (! $this->Query_ID) { - $this->halt("Invalid SQL: ".$Query_String, $line, $file); - } - - return $this->Query_ID; - } - - // public: perform a query with limited result set - function limit_query($Query_String, $offset, $line = '', $file = '', $num_rows = '') + class db { - global $phpgw_info; + var $Host = ''; + var $Database = ''; + var $User = ''; + var $Password = ''; - if (! $num_rows) + var $use_pconnect = False; + var $auto_stripslashes = False; + + /* "yes" (halt with message), "no" (ignore errors quietly), "report" (ignore errror, but spit a warning) */ + var $Halt_On_Error = 'yes'; + + var $Link_ID = 0; + var $Query_ID = 0; + var $Record = array(); + var $Row = 0; + + var $Seq_Table = 'db_sequence'; + + var $Errno = 0; + var $Error = ''; + + /* Set this to 1 for automatic pg_freeresult on last record. */ + var $Auto_Free = 0; + + function ifadd($add, $me) { - $num_rows = $phpgw_info['user']['preferences']['common']['maxmatchs']; + if('' != $add) return ' ' . $me . $add; } - if ($offset == 0) + /* public: constructor */ + function db($query = '') { - $Query_String .= ' LIMIT ' . $num_rows; - } - else - { - $Query_String .= ' LIMIT ' . $num_rows . ',' . $offset; + $this->query($query); } - if ($this->Debug) + function connect() { - printf("Debug: limit_query = %s
offset=%d, num_rows=%d
\n", $Query_String, $offset, $num_rows); - } - - return $this->query($Query_String, $line, $file); - } - - // public: discard the query result - function free() { - @pg_freeresult($this->Query_ID); - $this->Query_ID = 0; - } - - function next_record() { - $this->Record = @pg_fetch_array($this->Query_ID, $this->Row++); - - $this->Error = pg_ErrorMessage($this->Link_ID); - $this->Errno = ($this->Error == "")?0:1; - - $stat = is_array($this->Record); - if (!$stat && $this->Auto_Free) { - pg_freeresult($this->Query_ID); - $this->Query_ID = 0; - } - return $stat; - } - - function seek($pos) - { - $this->Row = $pos; - } - - function transaction_begin() - { - return $this->query('begin'); - } - - function transaction_commit() - { - if (! $this->Errno) - { - return pg_Exec($this->Link_ID,'commit'); - } - else - { - return False; - } - } - - function transaction_abort() - { - return pg_Exec($this->Link_ID,'rollback'); - } - - - function lock($table, $mode = 'write') - { - $result = $this->transaction_begin(); - - if ($mode == 'write') - { - if (is_array($table)) + if ( 0 == $this->Link_ID ) { - while ($t = each($table)) + $cstr = 'dbname=' . $this->Database + . $this->ifadd($this->Host, 'host=') + . $this->ifadd($this->Port, 'port=') + . $this->ifadd($this->User, 'user=') + . $this->ifadd($this->Password, 'password='); + if ($this->use_pconnect) { - $result = pg_Exec($this->Link_ID,'lock table ' . $t[1] . ' in share mode'); + $this->Link_ID=pg_pconnect($cstr); + } + else + { + $this->Link_ID=pg_connect($cstr); + } + if (!$this->Link_ID) + { + $this->halt('Link-ID == false, pconnect failed'); + } + } + } + + function limit($start) + { + global $phpgw_info; + + echo 'Warning: limit() is no longer used, use limit_query()'; + + if ($start == 0) + { + $s = 'limit ' . $phpgw_info['user']['preferences']['common']['maxmatchs']; + } + else + { + $s = 'limit ' . $phpgw_info['user']['preferences']['common']['maxmatchs'] . ',' . $start; + } + return $s; + } + + /* This only affects systems not using persistant connections */ + function disconnect() + { + return @pg_close($this->Link_ID); + } + + /* I added the line and file section so we can have better error reporting. (jengo) */ + function query($Query_String, $line = '', $file = '') + { + /* No empty queries, please, since PHP4 chokes on them. */ + /* The empty query string is passed on from the constructor, + * when calling the class without a query, e.g. in situations + * like these: '$db = new db_Subclass;' + */ + if ($Query_String == '') + { + return 0; + } + + $this->connect(); + + /* printf("
Debug: query = %s
\n", $Query_String); */ + + $this->Query_ID = pg_Exec($this->Link_ID, $Query_String); + $this->Row = 0; + + $this->Error = pg_ErrorMessage($this->Link_ID); + $this->Errno = ($this->Error == '') ? 0 : 1; + if (! $this->Query_ID) + { + $this->halt('Invalid SQL: ' . $Query_String, $line, $file); + } + + return $this->Query_ID; + } + + /* public: perform a query with limited result set */ + function limit_query($Query_String, $offset, $line = '', $file = '', $num_rows = '') + { + global $phpgw_info; + + if (! $num_rows) + { + $num_rows = $phpgw_info['user']['preferences']['common']['maxmatchs']; + } + + if ($offset == 0) + { + $Query_String .= ' LIMIT ' . $num_rows; + } + else + { + $Query_String .= ' LIMIT ' . $num_rows . ',' . $offset; + } + + if ($this->Debug) + { + printf("Debug: limit_query = %s
offset=%d, num_rows=%d
\n", $Query_String, $offset, $num_rows); + } + + return $this->query($Query_String, $line, $file); + } + + // public: discard the query result + function free() + { + @pg_freeresult($this->Query_ID); + $this->Query_ID = 0; + } + + function next_record() + { + $this->Record = @pg_fetch_array($this->Query_ID, $this->Row++); + + $this->Error = pg_ErrorMessage($this->Link_ID); + $this->Errno = ($this->Error == '') ? 0 : 1; + + $stat = is_array($this->Record); + if (!$stat && $this->Auto_Free) + { + pg_freeresult($this->Query_ID); + $this->Query_ID = 0; + } + return $stat; + } + + function seek($pos) + { + $this->Row = $pos; + } + + function transaction_begin() + { + return $this->query('begin'); + } + + function transaction_commit() + { + if (! $this->Errno) + { + return pg_Exec($this->Link_ID,'commit'); + } + else + { + return False; + } + } + + function transaction_abort() + { + return pg_Exec($this->Link_ID,'rollback'); + } + + function lock($table, $mode = 'write') + { + $result = $this->transaction_begin(); + + if ($mode == 'write') + { + if (is_array($table)) + { + while ($t = each($table)) + { + $result = pg_Exec($this->Link_ID,'lock table ' . $t[1] . ' in share mode'); + } + } + else + { + $result = pg_Exec($this->Link_ID, 'lock table ' . $table . ' in share mode'); } } else { - $result = pg_Exec($this->Link_ID, "lock table $table in share mode"); + $result = 1; + } + + return $result; + } + + function unlock() + { + return $this->transaction_commit(); + } + + + /* public: sequence numbers */ + function nextid($seq_name) + { + $this->connect(); + + if ($this->lock($this->Seq_Table)) + { + /* get sequence number (locked) and increment */ + $q = sprintf("select nextid from %s where seq_name = '%s'", + $this->Seq_Table, + $seq_name); + $id = @pg_Exec($this->Link_ID, $q); + $res = @pg_Fetch_Array($id, 0); + + /* No current value, make one */ + if (!is_array($res)) + { + $currentid = 0; + $q = sprintf("insert into %s values('%s', %s)", + $this->Seq_Table, + $seq_name, + $currentid); + $id = @pg_Exec($this->Link_ID, $q); + } + else + { + $currentid = $res['nextid']; + } + $nextid = $currentid + 1; + $q = sprintf("update %s set nextid = '%s' where seq_name = '%s'", + $this->Seq_Table, + $nextid, + $seq_name); + $id = @pg_Exec($this->Link_ID, $q); + $this->unlock(); + } + else + { + $this->halt('cannot lock ' . $this->Seq_Table . ' - has it been created?'); + return 0; + } + return $nextid; + } + + function metadata($table) + { + $count = 0; + $id = 0; + $res = array(); + + $this->connect(); + $id = pg_exec($this->Link_ID, "select * from $table"); + if ($id < 0) + { + $this->Error = pg_ErrorMessage($id); + $this->Errno = 1; + $this->halt('Metadata query failed.'); + } + $count = pg_NumFields($id); + + for ($i=0; $i<$count; $i++) + { + $res[$i]['table'] = $table; + $res[$i]['name'] = pg_FieldName ($id, $i); + $res[$i]['type'] = pg_FieldType ($id, $i); + $res[$i]['len'] = pg_FieldSize ($id, $i); + $res[$i]['flags'] = ''; + } + + pg_FreeResult($id); + return $res; + } + + function affected_rows() + { + return pg_cmdtuples($this->Query_ID); + } + + function num_rows() + { + return pg_numrows($this->Query_ID); + } + + function num_fields() + { + return pg_numfields($this->Query_ID); + } + + function nf() + { + return $this->num_rows(); + } + + function np() + { + print $this->num_rows(); + } + + function f($Name,$strip_slashes = '') + { + if ($strip_slashes || ($this->auto_stripslashes && ! $strip_slashes)) + { + return stripslashes($this->Record[$Name]); + } + else + { + return $this->Record[$Name]; } } - else + + function p($Name) { - $result = 1; + print $this->Record[$Name]; } - return $result; - } - - function unlock() - { - return $this->transaction_commit(); + function halt($msg, $line = "", $file = "") + { + global $phpgw; + + if($this->Halt_On_Error == "no") + { + return; + } + /* Just in case there is a table currently locked */ + $this->unlock(); + + printf("Database error: %s
\n", $msg); + printf("PostgreSQL Error: %s (%s)
\n", + $this->Errno, + $this->Error); + if ($file) + { + printf("
File: %s",$file); + } + if ($line) + { + printf("
Line: %s",$line); + } + + if ($this->Halt_On_Error == 'yes') + { + echo '

Session halted.'; + $phpgw->common->phpgw_exit(True); + } + } + + function table_names() + { + $this->query("select relname from pg_class where relkind = 'r' and not relname like 'pg_%'"); + $i=0; + while ($this->next_record()) + { + $return[$i]['table_name']= $this->f(0); + $return[$i]['tablespace_name']=$this->Database; + $return[$i]['database']=$this->Database; + $i++; + } + return $return; + } + + function create_database($adminname = '', $adminpasswd = '') + { + $currentUser = $this->User; + $currentPassword = $this->Password; + $currentDatabase = $this->Database; + + if ($adminname != "") + { + $this->User = $adminname; + $this->Password = $adminpasswd; + } + + if (! $this->Host) + { + system('createdb ' . $currentDatabase, $outval); + } + else + { + system('createdb -h ' . $this->Host . ' ' . $currentDatabase, $outval); + } + + if($outval != 0) + { + /* either the rights r not available or the postmaster is not running .... */ + echo 'database creation failure
'; + echo 'please setup the postreSQL database manually
'; + } + + $this->User = $currentUser; + $this->Password = $currentPassword; + $this->Database = $currentDatabase; + $this->connect(); + //return $return; + } } - - /* public: sequence numbers */ - function nextid($seq_name) { - $this->connect(); - - if ($this->lock($this->Seq_Table)) { - /* get sequence number (locked) and increment */ - $q = sprintf("select nextid from %s where seq_name = '%s'", - $this->Seq_Table, - $seq_name); - $id = @pg_Exec($this->Link_ID, $q); - $res = @pg_Fetch_Array($id, 0); - - /* No current value, make one */ - if (!is_array($res)) { - $currentid = 0; - $q = sprintf("insert into %s values('%s', %s)", - $this->Seq_Table, - $seq_name, - $currentid); - $id = @pg_Exec($this->Link_ID, $q); - } else { - $currentid = $res["nextid"]; - } - $nextid = $currentid + 1; - $q = sprintf("update %s set nextid = '%s' where seq_name = '%s'", - $this->Seq_Table, - $nextid, - $seq_name); - $id = @pg_Exec($this->Link_ID, $q); - $this->unlock(); - } else { - $this->halt("cannot lock ".$this->Seq_Table." - has it been created?"); - return 0; - } - return $nextid; - } - - - - function metadata($table) { - $count = 0; - $id = 0; - $res = array(); - - $this->connect(); - $id = pg_exec($this->Link_ID, "select * from $table"); - if ($id < 0) { - $this->Error = pg_ErrorMessage($id); - $this->Errno = 1; - $this->halt("Metadata query failed."); - } - $count = pg_NumFields($id); - - for ($i=0; $i<$count; $i++) { - $res[$i]["table"] = $table; - $res[$i]["name"] = pg_FieldName ($id, $i); - $res[$i]["type"] = pg_FieldType ($id, $i); - $res[$i]["len"] = pg_FieldSize ($id, $i); - $res[$i]["flags"] = ""; - } - - pg_FreeResult($id); - return $res; - } - - function affected_rows() { - return pg_cmdtuples($this->Query_ID); - } - - function num_rows() { - return pg_numrows($this->Query_ID); - } - - function num_fields() { - return pg_numfields($this->Query_ID); - } - - function nf() { - return $this->num_rows(); - } - - function np() { - print $this->num_rows(); - } - - function f($Name,$strip_slashes = "") - { - if ($strip_slashes || ($this->auto_stripslashes && ! $strip_slashes)) { - return stripslashes($this->Record[$Name]); - } else { - return $this->Record[$Name]; - } - } - - function p($Name) { - print $this->Record[$Name]; - } - - function halt($msg, $line = "", $file = "") - { - global $phpgw; - - if($this->Halt_On_Error == "no") { - return; - } - $this->unlock(); // Just in case there is a table currently locked - - printf("Database error: %s
\n", $msg); - printf("PostgreSQL Error: %s (%s)
\n", - $this->Errno, - $this->Error); - if ($file) { - printf("
File: %s",$file); - } - if ($line) { - printf("
Line: %s",$line); - } - - if ($this->Halt_On_Error == "yes") { - echo "

Session halted."; - $phpgw->common->phpgw_exit(True); - } - } - - function table_names() { - $this->query("select relname from pg_class where relkind = 'r' and not relname like 'pg_%'"); - $i=0; - while ($this->next_record()) - { - $return[$i]["table_name"]= $this->f(0); - $return[$i]["tablespace_name"]=$this->Database; - $return[$i]["database"]=$this->Database; - $i++; - } - return $return; - } - - function create_database($adminname = "", $adminpasswd = "") { - $currentUser = $this->User; - $currentPassword = $this->Password; - $currentDatabase = $this->Database; - - if ($adminname != "") - { - $this->User = $adminname; - $this->Password = $adminpasswd; - } - - if (! $this->Host) - { - system('createdb ' . $currentDatabase, $outval); - } - else - { - system('createdb -h ' . $this->Host . ' ' . $currentDatabase, $outval); - } - - if($outval != 0) - { - /* either the rights r not available or the postmaster is not running .... */ - echo 'database creation faliure
'; - echo 'please setup the postreSQL database manually
'; - } - - $this->User = $currentUser; - $this->Password = $currentPassword; - $this->Database = $currentDatabase; - $this->connect(); - //return $return; - } -}