18 include_once (
'Class.Log.php');
19 include_once (
'Lib.Common.php');
77 static private $masterLock =
false;
119 $this->log =
new Log(
"",
"DbObj", $this->dbtable);
121 if ($this->dbid == 0) {
125 $this->selectstring =
"";
127 reset($this->fields);
128 foreach ($this->fields as $k => $v) {
129 $this->selectstring = $this->selectstring . $this->dbtable .
"." . $v .
",";
133 reset($this->sup_fields);
134 foreach ($this->sup_fields as $k => $v) {
135 $this->selectstring = $this->selectstring .
"" . $v .
",";
138 $this->selectstring = substr($this->selectstring, 0, strlen($this->selectstring) - 1);
139 if (self::$sqlStrict === null) {
140 self::$sqlStrict = (
getParam(
'CORE_SQLSTRICT') !=
'no');
143 if (($id !=
'') || (is_array($id)) || (!isset($this->id_fields[0]))) {
149 if (is_array(
$res)) {
163 if (!$id)
return false;
164 if ($this->dbid == - 1)
return FALSE;
166 $msg = $this->PreSelect($id);
167 if ($msg !=
'')
return $msg;
169 if ($this->dbtable ==
'') {
170 return (
"error : No Tables");
172 $fromstr =
"{$this->dbtable}";
173 if (is_array($this->sup_tables)) {
174 reset($this->sup_tables);
175 foreach ($this->sup_tables as $k => $v) {
179 $sql =
"select {$this->selectstring} from {$fromstr} ";
184 $wherestr =
" where ";
185 reset($this->id_fields);
186 foreach ($this->id_fields as $k => $v) {
188 $wherestr = $wherestr .
" AND ";
190 $wherestr = $wherestr .
"( " . $this->dbtable .
"." . $v .
"=E'" . pg_escape_string($id[$k]) .
"' )";
196 if (isset($this->id_fields[0])) {
197 $k = $this->id_fields[0];
199 $wherestr =
"where " . $this->dbtable .
"." . $this->id_fields[0] .
"=E'" . pg_escape_string($id) .
"'";
204 if (is_array($this->sup_where)) {
205 reset($this->sup_where);
206 foreach ($this->sup_where as $k => $v) {
207 $wherestr = $wherestr .
" AND ";
208 $wherestr = $wherestr .
"( " . $v .
" )";
223 $msg = $this->PostSelect($id);
224 if ($msg !=
'')
return $msg;
234 foreach ($this->fields as $k => $v) {
247 if ($this->dbid == - 1)
return FALSE;
250 if (count(
$fields) == 0)
return true;
251 if ($this->dbtable ==
'') {
252 return (
"error : No Tables");
256 foreach ($this->id_fields as $id) {
257 $w[] =
"($id = E'" . pg_escape_string($this->$id) .
"') ";
259 $sqlwhere = implode(
"and", $w);
260 $sqlselect = implode(
",",
$fields);
262 $sql =
"select $sqlselect from $fromstr where $sqlwhere";
280 foreach ($array as $k => $v) {
281 if (!is_integer($k)) {
413 function Add($nopost =
false, $nopre =
false)
415 if ($this->dbid == - 1)
return FALSE;
417 if (!$nopre) $msg = $this->PreInsert();
418 if ($msg !=
'')
return $msg;
420 $sfields = implode(
",", $this->fields);
421 $sql =
"insert into " . $this->dbtable .
"($sfields) values (";
424 reset($this->fields);
425 foreach ($this->fields as $k => $v) {
426 $valstring = $valstring . $this->
lw(isset($this->$v) ? $this->$v :
'') .
",";
428 $valstring = substr($valstring, 0, strlen($valstring) - 1);
437 if (!$nopost) $msg = $this->PostInsert();
449 public function modify($nopost =
false, $sfields =
"", $nopre =
false)
452 if ($this->dbid == - 1)
return FALSE;
453 if (!$nopre) $msg = $this->PreUpdate();
454 if ($msg !=
'')
return $msg;
455 $sql =
"update " . $this->dbtable .
" set ";
462 foreach ($this->id_fields as $k => $v)
$fields[] = $v;
466 foreach ($this->id_fields as $k => $v) {
469 $val = pg_escape_string($this->$v);
470 $wstr = $wstr .
" " . $v .
"=E'" . $val .
"' AND";
474 foreach (
$fields as $k => $v) {
475 if (!isset($notset[$v])) {
476 $setstr = $setstr .
" " . $v .
"=" . $this->
lw(isset($this->$v) ? $this->$v :
'') .
",";
479 $setstr = substr($setstr, 0, strlen($setstr) - 1);
480 $wstr = substr($wstr, 0, strlen($wstr) - 3);
483 $sql.=
" where " . $wstr .
";";
492 if (!$nopost) $msg = $this->PostUpdate();
501 public function delete($nopost =
false)
503 $msg = $this->PreDelete();
504 if ($msg !=
'')
return $msg;
508 reset($this->id_fields);
509 foreach ($this->id_fields as $k => $v) {
511 $wherestr = $wherestr .
" AND ";
513 $wherestr = $wherestr .
"( " . $v .
"=E'" . pg_escape_string($this->$v) .
"' )";
517 $sql =
"delete from " . $this->dbtable .
" where " . $wherestr .
";";
525 if (!$nopost) $msg = $this->PostDelete();
536 function Adds(&$tcopy, $nopost =
false)
538 if ($this->dbid == - 1)
return FALSE;
539 if (!is_array($tcopy))
return FALSE;
541 $sfields = implode(
",", $this->fields);
542 $sql =
"copy " . $this->dbtable .
"($sfields) from STDIN;\n";
545 foreach ($tcopy as $kc => $vc) {
547 foreach ($this->fields as $k => $v) {
548 $trow[$kc].=
"" . ((isset($vc[$v])) ? $vc[$v] : ((($this->$v) !=
'') ? $this->$v :
'\N')) .
"\t";
552 $trow[$kc] = substr($trow[$kc], 0, -1);
555 $berr = pg_copy_from($this->dbid, $this->dbtable, $trow,
"\t");
557 if (!$berr)
return sprintf(_(
"DbObj::Adds error in multiple insertion"));
559 if (!$nopost) $msg = $this->PostInsert();
564 $result = (($prop ==
'') && ($prop !== 0)) ?
"null" :
"E'" . pg_escape_string($prop) .
"'";
569 pg_close(
"$this->dbid");
576 if (isset($this->sqlcreate)) {
578 if (is_array($this->sqlcreate)) {
579 foreach ($this->sqlcreate as $k => $sqlquery) {
583 $sqlcmds = explode(
";", $this->sqlcreate);
584 foreach ($sqlcmds as $k => $sqlquery) {
588 $this->log->debug(
"DbObj::Create : " . print_r($this->sqlcreate,
true));
590 if (isset($this->sqlinit)) {
592 $this->log->debug(
"Init : {$this->sqlinit}");
595 $this->log->info(
"DbObj::Create $msg");
598 if (!$nopost) $this->PostInit();
609 if ($this->dbaccess ==
"") {
613 $this->dbid =
getDbid($this->dbaccess);
614 if ($this->dbid == 0) error_log(__METHOD__ .
"null dbid");
621 $this->err_code = pg_result_error_field($this->res, PGSQL_DIAG_SQLSTATE);
625 if ($this->err_code !=
"") {
627 switch ($this->err_code) {
630 $action_needed =
"create";
635 $action_needed =
"update";
640 $action_needed =
"none";
653 switch ($action_needed) {
661 $this->msg_err = $originError .
"\n" .
$err;
702 if (
$sql ==
"")
return '';
704 if ($SQLDEBUG) $sqlt1 = microtime();
706 $this->log->debug(
"exec_query : $sql");
707 $this->msg_err = $this->err_code =
'';
709 if (pg_send_prepare($this->dbid,
'',
$sql) ===
false) {
711 error_log(__METHOD__ .
" " . $this->msg_err);
714 $this->res = pg_get_result($this->dbid);
715 $err = pg_result_error($this->res);
718 $this->err_code = pg_result_error_field($this->res, PGSQL_DIAG_SQLSTATE);
721 if ($this->msg_err ==
"") {
722 if (pg_send_execute($this->dbid,
'', array()) ===
false) {
729 $this->res = pg_get_result($this->dbid);
730 $err = pg_result_error($this->res);
733 $this->err_code = pg_result_error_field($this->res, PGSQL_DIAG_SQLSTATE);
737 if (pg_send_query($this->dbid,
$sql) ===
false) {
743 $this->res = pg_get_result($this->dbid);
744 while (pg_get_result($this->dbid));
745 $err = pg_result_error($this->res);
748 $this->err_code = pg_result_error_field($this->res, PGSQL_DIAG_SQLSTATE);
752 if ($this->msg_err && ($lvl == 0)) {
760 catch(Exception $e) {
761 $this->msg_err = $orierr;
764 if ($this->msg_err !=
"") {
765 $this->log->warning(
"exec_query :" .
$sql);
766 $this->log->warning(
"PostgreSQL Error : " . $this->msg_err);
775 $TSQLDELAY[] = array(
777 "s" => str_replace(array(
788 return ($this->msg_err);
797 if ($this->msg_err ==
"") {
798 return (pg_num_rows($this->res));
807 return (pg_fetch_array($this->res,
$c,
$type));
820 $err = $this->msg_err .
"\n" . $moreerr .
"\n";
822 if (self::$sqlStrict) {
835 print (
" - need update table " . $this->dbtable);
836 $this->log->error(
"need Update table " . $this->dbtable);
838 $this->log->info(
"Update table " . $this->dbtable);
840 $objupdate =
new DbObj($this->dbaccess);
843 $dumpfile = uniqid(
getTmpDir() .
"/" . $this->dbtable);
844 $err = $objupdate->exec_query(
"COPY " . $this->dbtable .
" TO '" . $dumpfile .
"'");
845 $this->log->info(
"Dump table " . $this->dbtable .
" in " . $dumpfile);
852 $err = $objupdate->exec_query(
"ALTER TABLE " . $this->dbtable .
" RENAME TO " . $this->dbtable .
"_old", 1);
856 $err = $this->
exec_query(
"select indexname from pg_indexes where tablename='" . $this->dbtable .
"_old'", 1);
858 for (
$c = 0;
$c < $nbidx;
$c++) {
861 $err = $objupdate->exec_query(
"DROP INDEX " . $row[
"indexname"], 1);
870 $this->
exec_query(
"SELECT * FROM " . $this->dbtable .
"_old");
872 for (
$c = 0;
$c < $nbold;
$c++) {
878 $inter_fields = array_intersect(array_keys($row) , $this->fields);
879 reset($this->fields);
881 foreach ($inter_fields as $k => $v) {
890 reset($inter_fields);
891 foreach ($inter_fields as $k => $v) {
892 $values.=
"E'" . pg_escape_string($row[$v]) .
"',";
894 $values = substr($values, 0, strlen($values) - 1);
897 $sqlInsert = sprintf(
"INSERT INTO %s %s VALUES ", $this->dbtable,
$fields, $values);
898 $err = $objupdate->exec_query($sqlInsert, 1);
903 $err = $objupdate->exec_query(
"DROP TABLE " . $this->dbtable .
"_old", 1);
916 $err = sprintf(
"dbid is null cannot save point %s",
$point);
917 error_log(__METHOD__ .
":$err");
920 if ($this->debug) error_log(
'[DBG]' .
'BEFORE' . __METHOD__ . $this->dbid);
923 $idbid = intval($this->dbid);
925 if (empty(self::$savepoint[$idbid])) {
926 self::$savepoint[$idbid] = array(
930 if ($this->debug) error_log(
'[DBG]' . __METHOD__ .
"add(1) $point");
932 self::$savepoint[$idbid][] =
$point;
933 if ($this->debug) error_log(
'[DBG]' . __METHOD__ .
"add(2) $point");
940 if ($this->debug) error_log(
'[DBG]' .
'AFTER' . __METHOD__ . $idbid .
":$point:" . implode(
',', self::$savepoint[$idbid]));
941 if (
$err) error_log(__METHOD__ .
":$err");
960 public function lockPoint($exclusiveLock, $exclusiveLockPrefix =
'')
962 if (($exclusiveLock_int32 = \Dcp\Utils\Types::to_int32($exclusiveLock)) ===
false) {
963 throw new \Dcp\Db\Exception(
"DB0012", var_export($exclusiveLock,
true));
965 $exclusiveLock = $exclusiveLock_int32;
967 $err = sprintf(
"dbid is null cannot add lock %s-%s", $exclusiveLock, $exclusiveLockPrefix);
968 error_log(__METHOD__ .
":$err");
973 $idbid = intval($this->dbid);
974 if (empty(self::$savepoint[$idbid])) {
975 throw new \Dcp\Db\Exception(
"DB0011", $exclusiveLock, $exclusiveLockPrefix);
978 if ($exclusiveLockPrefix) {
979 if (strlen($exclusiveLockPrefix) > 4) {
980 throw new \Dcp\Db\Exception(
"DB0010", $exclusiveLockPrefix);
982 $prefixLockId = unpack(
"i", str_pad($exclusiveLockPrefix, 4)) [1];
986 if (self::$masterLock ===
false) {
987 $err = $this->
exec_query(sprintf(
'select pg_advisory_lock(0), pg_advisory_unlock(0), pg_advisory_xact_lock(%d,%d);', $exclusiveLock, $prefixLockId));
992 self::$lockpoint[$idbid][sprintf(
"%d-%s", $exclusiveLock, $exclusiveLockPrefix) ] = array(
1010 $err = sprintf(
"dbid is null cannot add master lock ");
1011 error_log(__METHOD__ .
":$err");
1023 self::$masterLock = (bool)$useLock;
1034 $err = sprintf(
"dbid is null cannot save point %s",
$point);
1035 error_log(__METHOD__ .
":$err");
1038 $idbid = intval($this->dbid);
1039 if (isset(self::$savepoint[$idbid])) $lastPoint = array_search(
$point, self::$savepoint[$idbid]);
1040 else $lastPoint =
false;
1041 if ($lastPoint !==
false) {
1043 self::$savepoint[$idbid] = array_slice(self::$savepoint[$idbid], 0, $lastPoint);
1045 if ((!
$err) && (count(self::$savepoint[$idbid]) == 0)) {
1049 $err = sprintf(
"cannot rollback unsaved point : %s",
$point);
1052 if ($this->debug) error_log(
'[DBG]' . __METHOD__ .
":$point:" . implode(
',', self::$savepoint[$idbid]));
1053 if (
$err) error_log(__METHOD__ .
":$err");
1064 $err = sprintf(
"dbid is null cannot save point %s",
$point);
1065 error_log(__METHOD__ .
":$err");
1068 $idbid = intval($this->dbid);
1069 if ($this->debug) error_log(
'[DBG]' . __METHOD__ .
":$point:" . implode(
',', self::$savepoint[$idbid]));
1071 $lastPoint = array_search(
$point, self::$savepoint[$idbid]);
1073 if ($lastPoint !==
false) {
1074 self::$savepoint[$idbid] = array_slice(self::$savepoint[$idbid], 0, $lastPoint);
1076 if ((!
$err) && (count(self::$savepoint[$idbid]) == 0)) {
1080 $err = sprintf(
"cannot commit unsaved point : %s",
$point);
1082 if (
$err) error_log(__METHOD__ .
":$err");
logDebugStack($slice=1, $msg="")
exec_query($sql, $lvl=0, $prepare=false)
Add($nopost=false, $nopre=false)
static getError($code, $args=null)
Adds(&$tcopy, $nopost=false)
fetch_array($c, $type=PGSQL_ASSOC)
__construct($dbaccess= '', $id= '', $res= '', $dbid=0)
modify($nopost=false, $sfields="", $nopre=false)
lockPoint($exclusiveLock, $exclusiveLockPrefix= '')
getParam($name, $def="")
must be in core or global type
if($updateExistingTable) $point
affectColumn($fields, $reset=true)
if($file) if($subject==""&&$file) if($subject=="") $err
affect($array, $more=false, $reset=true)