<commit_before><?php
/**
 * This class is a generic DB Class that can be used to create objects
 * based on the description of a DB Table. 
 *
 * @author Anakeen 2000 
 * @version $Id: Class.DbObj.php,v 1.47 2007/05/10 13:06:22 eric Exp $
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 * @package WHAT
 * @subpackage CORE
 */
 /**
 */

// ---------------------------------------------------------------------------
// Db Object
// @version $Id: Class.DbObj.php,v 1.47 2007/05/10 13:06:22 eric Exp $
// ---------------------------------------------------------------------------
// Anakeen 2000 - <EMAIL>
// ---------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at
//  your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ---------------------------------------------------------------------------




include_once('Class.Log.php');
include_once('Lib.Common.php');

$CLASS_DBOBJ_PHP = '$Id: Class.DbObj.php,v 1.47 2007/05/10 13:06:22 eric Exp $';

/**
 * This class is a generic DB Class that can be used to create objects
 * based on the description of a DB Table. More Complex Objects will 
 * inherit from this basic Class.
 *
 */
Class DbObj 
{

/**
 * the database connection resource
 * @var resource 
 */
var $dbid = -1;
/**
 * coordinates to access to database
 * @var string 
 */
var $dbaccess = '';

/**
 * array of SQL fields use for the object 
 * @var array 
 */
var $fields=array ('*');

/**
 * name of the SQL table
 * @var string  
 */
var $dbtable='';

var $criterias=array();
/**
 * array of other SQL fields, not in attribute of object
 * @var array 
 */
var $sup_fields=array ();
var $sup_where=array ();
var $sup_tables=array ();
var $fulltextfields=array ();

/**
 * sql field to order
 * @var string 
 */
var $order_by="";
/**
 * indicates if fields has been affected 
 * @var string 
 * @see Affect()
 */
var $isset = false; // indicate if fields has been affected (call affect methods)

//----------------------------------------------------------------------------
/** 
 * Database Object constructor
 * 
 * 
 * @param string $dbaccess database specification
 * @param int $id identificator of the object
 * @param array $res array of result issue to QueryDb {@link QueryDb::Query()}
 * @param resource $dbid the database connection resource
 * @return bool false if error occured
 */
function __construct($dbaccess='', $id='',$res='',$dbid=0)
  {
    
    $this->dbaccess = $dbaccess;
    $this->init_dbid();


  
    //global ${$this->oname};
    $this->log = new Log("","DbObj",$this->dbtable);
    

    if ($this->dbid == 0) {
      $this->dbid = -1;      
    }

    $this->selectstring="";
    // SELECTED FIELDS
    reset($this->fields);
    while(list($k,$v) = each($this->fields)) {
      $this->selectstring=$this->selectstring.$this->dbtable.".".$v.",";
      $this->$v="";
    }

    reset($this->sup_fields);
    while (list($k,$v) = each($this->sup_fields)) {
      $this->selectstring=$this->selectstring."".$v.",";
      $this->$v="";
    }  
    $this->selectstring=substr($this->selectstring,0,strlen($this->selectstring)-1);

    // select with the id
    if (($id!='') || (is_array($id)) || (!isset($this->id_fields[0])) ) {
      $ret=$this->Select($id);

      return($ret);
    }
    // affect with a query result
    if (is_array($res)) {
      $this->Affect($res);
    }


    return TRUE;
  }






function Select($id)
  {
    if ($this->dbid == -1) return FALSE;
    
    $msg=$this->PreSelect($id);
    if ($msg!='') return $msg;
    
    if ($this->dbtable=='') {
      return("error : No Tables");
    }
    $fromstr="{$this->dbtable}"; 
    if (is_array($this->sup_tables)) {
      reset($this->sup_tables);
      while(list($k,$v) = each($this->sup_tables)) {
	$fromstr.=",".$v;
      }
    } 
    $sql = "select {$this->selectstring} from {$fromstr} ";
    
    $count=0;
    if (is_array($id)) {
      $count=0;
      $wherestr=" where "; 
      reset($this->id_fields);
      while(list($k,$v) = each($this->id_fields)) {
	if ($count >0) {
	  $wherestr=$wherestr." AND ";
	}
	$wherestr=$wherestr."( ".$this->dbtable.".".$v."='".$id[$k]."' )";
	$count=$count+1;
	
	//$this->$v = $id[$k];
      }
    } else {
      if (isset($this->id_fields[0])) {
	$k = $this->id_fields[0];
	//$this->$k = $id;
	$wherestr= "where ".$this->dbtable.".".$this->id_fields[0]."='".$id."'" ;
      } else {
	$wherestr="";
      }
    }
    if (is_array($this->sup_where)) {
      reset($this->sup_where);
      while(list($k,$v) = each($this->sup_where)) {
	$wherestr=$wherestr." AND ";
	$wherestr=$wherestr."( ".$v." )";
	$count=$count+1;
      }
    } 
    
    $sql=$sql." ".$wherestr;
    
    $resultat = $this->exec_query($sql);
    
    if ($this->numrows() > 0) {
      $res = $this->fetch_array(0);
      $retour = $this->Affect($res);
      
    } else {
      return FALSE;
    }
    $msg=$this->PostSelect($id);
    if ($msg!='') return $msg;
    return TRUE;
  }


function Affect($array)
  {
    reset($array);
    while(list($k,$v) = each($array)) {
      if (!is_integer($k)) {
	$this->$k = $v;
      }
    }
    $this->Complete();
    $this->isset = true;
  }
 /**
   * verify that the object exists 
   *
   * if true values of the object has been set
   * @return bool
   */
function isAffected()
  {
    return $this->isset;
  }

function Complete()
  {
    // This function should be replaced by the Child Class
  }

/** 
 * Method use before Add method
 * This method should be replaced by the Child Class
 * 
 * @return string error message, if no error empty string
 * @see Add()
 */
function PreInsert()
  {
    // This function should be replaced by the Child Class
  }
/** 
 * Method use after Add method
 * This method should be replaced by the Child Class
 * 
 * @return string error message, if no error empty string, if message
 * error not empty the Add method is not completed
 * @see Add()
 */
function PostInsert()
  {
    // This function should be replaced by the Child Class
  }
/** 
 * Method use before Modify method
 * This method should be replaced by the Child Class
 * 
 * @return string error message, if no error empty string
 * @see Modify()
 */
function PreUpdate()
  {
    // This function should be replaced by the Child Class
  }
/** 
 * Method use after Modify method
 * This method should be replaced by the Child Class
 * 
 * @return string error message, if no error empty string, if message
 * error not empty the Modify method is not completed
 * @see Modify()
 */
function PostUpdate()
  {
    // This function should be replaced by the Child Class
  }
function PreDelete()
  {
    // This function should be replaced by the Child Class
  }
function PostDelete()
  {
    // This function should be replaced by the Child Class
  }
function PreSelect($id)
  {
    // This function should be replaced by the Child Class
  }
function PostSelect($id)
  {
    // This function should be replaced by the Child Class
  }

/** 
 * Add the object to the database
 * @param bool $nopost PostInsert method not apply if true
 * @return string error message, if no error empty string
 * @see PreInsert()
 * @see PostInsert()
 */
function Add($nopost=false)
  {
    if ($this->dbid == -1) return FALSE;
    
    $msg=$this->PreInsert();
    if ($msg!='') return $msg;
    
    $sfields = implode(",",$this->fields);
    $sql = "insert into ".$this->dbtable. "($sfields) values (";
    
    $valstring = "";
    reset($this->fields);
    while (list($k,$v) = each($this->fields)) {
      $valstring = $valstring.$this->lw(AddSlashes($this->$v)).",";
    }
    $valstring=substr($valstring,0,strlen($valstring)-1);
    $sql=$sql.$valstring.")";
    
    // requery execution
      $msg_err = $this->exec_query($sql);
    
    if ($msg_err!=''){
      return $msg_err;
    }
    $this->isset=true;
    if (!$nopost) $msg=$this->PostInsert();
    if ($msg!='') return $msg;
  }
/** 
 * Add the object to the database
 * @param bool $nopost PostUpdate() and method not apply if true
 * @param string $sfields only this column will ne updated if empty all fields
 * @param bool $nopre PreUpdate() method not apply if true
 * @return string error message, if no error empty string
 * @see PreUpdate()
 * @see PostUpdate()
 */
function Modify($nopost=false,$sfields="",$nopre=false)
  {
    if ($this->dbid == -1) return FALSE;
    if (!$nopre) $msg=$this->PreUpdate();
    if ($msg!='') return $msg;
    $sql = "update ".$this->dbtable." set ";
    
    
   
    $nb_keys=0;
    foreach ($this->id_fields as $k=>$v) {
      $notset[$v]="Y";
      $nb_keys++;
    }

    if (! is_array($sfields)) $fields=$this->fields;
    else {
      $fields=$sfields;
      foreach ($this->id_fields as $k=>$v) $fields[]=$v;
    }
    

    $setstr="";
    $wstr="";
    foreach ($fields as $k=>$v) {
      if (!isset($notset[$v])) {
        $setstr=$setstr." ".$v."=".$this->lw(AddSlashes($this->$v)).",";
      } else {
        $wstr=$wstr." ".$v."='".$this->$v."' AND";
      } 
    }
    $setstr=substr($setstr,0,strlen($setstr)-1);
    $wstr=substr($wstr,0,strlen($wstr)-3);
    $sql.=$setstr;
    if ($nb_keys>0) {
      $sql.=" where ".$wstr.";";
    }
    
    $msg_err = $this->exec_query($sql);

    // sortie
      if ($msg_err!=''){
	return $msg_err;
      }
    
    if (!$nopost) $msg=$this->PostUpdate();
    
    if ($msg!='') return $msg;
  }	

function Delete($nopost=false)
  {
    $msg=$this->PreDelete();
    if ($msg!='') return $msg;
    $wherestr="";
    $count=0;
    
    reset($this->id_fields);
    while(list($k,$v) = each($this->id_fields)) {
      if ($count >0) {
        $wherestr=$wherestr." AND ";
      }
      $wherestr=$wherestr."( ".$v."='".AddSlashes($this->$v)."' )";
      $count++;
    }
    
    // suppression de l'enregistrement
      $sql = "delete from ".$this->dbtable." where ".$wherestr.";";
    
    $msg_err = $this->exec_query($sql);
    
    if ($msg_err!=''){
      return $msg_err;
    }
    
    if (!$nopost) $msg=$this->PostDelete();
    if ($msg!='') return $msg;
  }
/** 
 * Add several objects to the database
 * no post neither preInsert are called
 * @param bool $nopost PostInsert method not apply if true
 * @return string error message, if no error empty string
 * @see PreInsert()
 * @see PostInsert()
 */
function Adds(&$tcopy, $nopost=false)
  {
    if ($this->dbid == -1) return FALSE;
    if (! is_array($tcopy)) return FALSE;
    
    $sfields = implode(",",$this->fields);
    $sql = "copy ".$this->dbtable. "($sfields) from STDIN;\n";
    
    $trow=array();
    foreach ($tcopy as $kc=>$vc) {
      $trow[$kc]="";
      foreach($this->fields as $k=>$v) {
	$trow[$kc] .= "".((isset($vc[$v]))?$vc[$v]:$this->$v)."\t";
	//$trow[$kc][$k] .= ((isset($vc[$v]))?$vc[$v]:$this->$v);
      }
      $trow[$kc]=substr($trow[$kc],0,-1);
    }
    
    // query execution
    $berr= pg_copy_from($this->dbid,$this->dbtable,$trow,"\t");
	 
    if (! $berr) return sprintf(_("DbObj::Adds error in multiple insertion"));

    
    if (!$nopost) $msg=$this->PostInsert();
    if ($msg!='') return $msg;
  }
function lw($prop)
  {
    $result = ($prop==''?"null":"'$prop'");
    return $result;
  }
function CloseConnect()
  {
    pg_close("$this->dbid");
    return TRUE;
  }

function Create($nopost=false)
  {
    $msg = "";
    if (isset($this->sqlcreate)) {
      // step by step
      if (is_array($this->sqlcreate)) {
	while (list($k,$sqlquery)=each($this->sqlcreate)) {
	  $msg.=$this->exec_query($sqlquery,1);
	}
      } else {	
	$sqlcmds = explode(";",$this->sqlcreate);
	while (list($k,$sqlquery)=each($sqlcmds)) {
	  $msg.=$this->exec_query($sqlquery,1);
	}
      }
      $this->log->debug("DbObj::Create : {$this->sqlcreate}");
    }
    if (isset($this->sqlinit)) {
      $msg=$this->exec_query($this->sqlinit,1);
      $this->log->debug("Init : {$this->sqlinit}");
    }
    if ($msg != '') {
      $this->log->info("DbObj::Create $msg");   
      return $msg;
    }
    if (!$nopost) $this->PostInit();
    return($msg);
  }  

function PostInit() {
}

function init_dbid() {
  
  if ($this->dbaccess=="") {
    // don't test if file exist or must be searched in include_path 
      include("dbaccess.php");
    $this->dbaccess=getDbAccess();
    
  }
  $this->dbid= getDbid($this->dbaccess);
  return $this->dbid;
  
}
function exec_query($sql,$lvl=0)
  {
    global $SQLDELAY,$SQLDEBUG;

    if ($sql == "") return;

    if ($SQLDEBUG) $sqlt1=microtime(); // to test delay of request
    //     $mb=microtime();
    $this->init_dbid();
    $this->log->debug("exec_query : $sql");
    
    $this->res=@pg_query($this->dbid,$sql);
    // print "<P> $sql;".$this->dbid; print sprintf(" - <B>%.03f</b></p>",microtime_diff(microtime(),$mb));
    $pgmess = pg_last_error($this->dbid);
    //    if ($pgmess != "") print "[$sql]";
    
    $this->msg_err = chop(ereg_replace("ERROR:  ","",$pgmess));
    
    
    $action_needed= "";
    if ($lvl==0) { // to avoid recursivity
      if ($this->msg_err != "") {
		     if ((eregi("Relation ['\"]([a-zA-Z_]*)['\"] does not exist",$this->msg_err) ||
			  eregi("Relation (.*) n'existe pas",$this->msg_err) ||
			  eregi("class \"([a-zA-Z_]*)\" not found",$this->msg_err)) ) {
		       $action_needed = "create";
		     } else if ((eregi("No such attribute or function '([a-zA-Z_0-9]*)'",$this->msg_err)) ||
				(eregi("Attribute ['\"]([a-zA-Z_0-9]*)['\"] not found",$this->msg_err))) {
		       $action_needed = "update";
		     } else if (eregi("relation ['\"](.*)['\"] already exists",$this->msg_err) ||
				eregi("relation (.*) existe d",$this->msg_err)){
		       $action_needed = "none";		       
		     }
		     //print "\n\t\t[".$this->msg_err."]:$action_needed\n";<commit_msg>Security fix for DbObj::modify : use explicit of pg_escape_string<commit_after><?php
/**
 * This class is a generic DB Class that can be used to create objects
 * based on the description of a DB Table. 
 *
 * @author Anakeen 2000 
 * @version $Id: Class.DbObj.php,v 1.48 2007/05/23 09:57:31 eric Exp $
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 * @package WHAT
 * @subpackage CORE
 */
 /**
 */

// ---------------------------------------------------------------------------
// Db Object
// @version $Id: Class.DbObj.php,v 1.48 2007/05/23 09:57:31 eric Exp $
// ---------------------------------------------------------------------------
// Anakeen 2000 - <EMAIL>
// ---------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at
//  your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ---------------------------------------------------------------------------




include_once('Class.Log.php');
include_once('Lib.Common.php');

$CLASS_DBOBJ_PHP = '$Id: Class.DbObj.php,v 1.48 2007/05/23 09:57:31 eric Exp $';

/**
 * This class is a generic DB Class that can be used to create objects
 * based on the description of a DB Table. More Complex Objects will 
 * inherit from this basic Class.
 *
 */
Class DbObj 
{

/**
 * the database connection resource
 * @var resource 
 */
var $dbid = -1;
/**
 * coordinates to access to database
 * @var string 
 */
var $dbaccess = '';

/**
 * array of SQL fields use for the object 
 * @var array 
 */
var $fields=array ('*');

/**
 * name of the SQL table
 * @var string  
 */
var $dbtable='';

var $criterias=array();
/**
 * array of other SQL fields, not in attribute of object
 * @var array 
 */
var $sup_fields=array ();
var $sup_where=array ();
var $sup_tables=array ();
var $fulltextfields=array ();

/**
 * sql field to order
 * @var string 
 */
var $order_by="";
/**
 * indicates if fields has been affected 
 * @var string 
 * @see Affect()
 */
var $isset = false; // indicate if fields has been affected (call affect methods)

//----------------------------------------------------------------------------
/** 
 * Database Object constructor
 * 
 * 
 * @param string $dbaccess database specification
 * @param int $id identificator of the object
 * @param array $res array of result issue to QueryDb {@link QueryDb::Query()}
 * @param resource $dbid the database connection resource
 * @return bool false if error occured
 */
function __construct($dbaccess='', $id='',$res='',$dbid=0)
  {
    
    $this->dbaccess = $dbaccess;
    $this->init_dbid();


  
    //global ${$this->oname};
    $this->log = new Log("","DbObj",$this->dbtable);
    

    if ($this->dbid == 0) {
      $this->dbid = -1;      
    }

    $this->selectstring="";
    // SELECTED FIELDS
    reset($this->fields);
    while(list($k,$v) = each($this->fields)) {
      $this->selectstring=$this->selectstring.$this->dbtable.".".$v.",";
      $this->$v="";
    }

    reset($this->sup_fields);
    while (list($k,$v) = each($this->sup_fields)) {
      $this->selectstring=$this->selectstring."".$v.",";
      $this->$v="";
    }  
    $this->selectstring=substr($this->selectstring,0,strlen($this->selectstring)-1);

    // select with the id
    if (($id!='') || (is_array($id)) || (!isset($this->id_fields[0])) ) {
      $ret=$this->Select($id);

      return($ret);
    }
    // affect with a query result
    if (is_array($res)) {
      $this->Affect($res);
    }


    return TRUE;
  }






function Select($id)
  {
    if ($this->dbid == -1) return FALSE;
    
    $msg=$this->PreSelect($id);
    if ($msg!='') return $msg;
    
    if ($this->dbtable=='') {
      return("error : No Tables");
    }
    $fromstr="{$this->dbtable}"; 
    if (is_array($this->sup_tables)) {
      reset($this->sup_tables);
      while(list($k,$v) = each($this->sup_tables)) {
	$fromstr.=",".$v;
      }
    } 
    $sql = "select {$this->selectstring} from {$fromstr} ";
    
    $count=0;
    if (is_array($id)) {
      $count=0;
      $wherestr=" where "; 
      reset($this->id_fields);
      while(list($k,$v) = each($this->id_fields)) {
	if ($count >0) {
	  $wherestr=$wherestr." AND ";
	}
	$wherestr=$wherestr."( ".$this->dbtable.".".$v."='".$id[$k]."' )";
	$count=$count+1;
	
	//$this->$v = $id[$k];
      }
    } else {
      if (isset($this->id_fields[0])) {
	$k = $this->id_fields[0];
	//$this->$k = $id;
	$wherestr= "where ".$this->dbtable.".".$this->id_fields[0]."='".$id."'" ;
      } else {
	$wherestr="";
      }
    }
    if (is_array($this->sup_where)) {
      reset($this->sup_where);
      while(list($k,$v) = each($this->sup_where)) {
	$wherestr=$wherestr." AND ";
	$wherestr=$wherestr."( ".$v." )";
	$count=$count+1;
      }
    } 
    
    $sql=$sql." ".$wherestr;
    
    $resultat = $this->exec_query($sql);
    
    if ($this->numrows() > 0) {
      $res = $this->fetch_array(0);
      $retour = $this->Affect($res);
      
    } else {
      return FALSE;
    }
    $msg=$this->PostSelect($id);
    if ($msg!='') return $msg;
    return TRUE;
  }


function Affect($array)
  {
    reset($array);
    while(list($k,$v) = each($array)) {
      if (!is_integer($k)) {
	$this->$k = $v;
      }
    }
    $this->Complete();
    $this->isset = true;
  }
 /**
   * verify that the object exists 
   *
   * if true values of the object has been set
   * @return bool
   */
function isAffected()
  {
    return $this->isset;
  }

function Complete()
  {
    // This function should be replaced by the Child Class
  }

/** 
 * Method use before Add method
 * This method should be replaced by the Child Class
 * 
 * @return string error message, if no error empty string
 * @see Add()
 */
function PreInsert()
  {
    // This function should be replaced by the Child Class
  }
/** 
 * Method use after Add method
 * This method should be replaced by the Child Class
 * 
 * @return string error message, if no error empty string, if message
 * error not empty the Add method is not completed
 * @see Add()
 */
function PostInsert()
  {
    // This function should be replaced by the Child Class
  }
/** 
 * Method use before Modify method
 * This method should be replaced by the Child Class
 * 
 * @return string error message, if no error empty string
 * @see Modify()
 */
function PreUpdate()
  {
    // This function should be replaced by the Child Class
  }
/** 
 * Method use after Modify method
 * This method should be replaced by the Child Class
 * 
 * @return string error message, if no error empty string, if message
 * error not empty the Modify method is not completed
 * @see Modify()
 */
function PostUpdate()
  {
    // This function should be replaced by the Child Class
  }
function PreDelete()
  {
    // This function should be replaced by the Child Class
  }
function PostDelete()
  {
    // This function should be replaced by the Child Class
  }
function PreSelect($id)
  {
    // This function should be replaced by the Child Class
  }
function PostSelect($id)
  {
    // This function should be replaced by the Child Class
  }

/** 
 * Add the object to the database
 * @param bool $nopost PostInsert method not apply if true
 * @return string error message, if no error empty string
 * @see PreInsert()
 * @see PostInsert()
 */
function Add($nopost=false)
  {
    if ($this->dbid == -1) return FALSE;
    
    $msg=$this->PreInsert();
    if ($msg!='') return $msg;
    
    $sfields = implode(",",$this->fields);
    $sql = "insert into ".$this->dbtable. "($sfields) values (";
    
    $valstring = "";
    reset($this->fields);
    while (list($k,$v) = each($this->fields)) {
      $valstring = $valstring.$this->lw($this->$v).",";
    }
    $valstring=substr($valstring,0,strlen($valstring)-1);
    $sql=$sql.$valstring.")";
    
    // requery execution
      $msg_err = $this->exec_query($sql);
    
    if ($msg_err!=''){
      return $msg_err;
    }
    $this->isset=true;
    if (!$nopost) $msg=$this->PostInsert();
    if ($msg!='') return $msg;
  }
/** 
 * Add the object to the database
 * @param bool $nopost PostUpdate() and method not apply if true
 * @param string $sfields only this column will ne updated if empty all fields
 * @param bool $nopre PreUpdate() method not apply if true
 * @return string error message, if no error empty string
 * @see PreUpdate()
 * @see PostUpdate()
 */
function Modify($nopost=false,$sfields="",$nopre=false)
  {
    if ($this->dbid == -1) return FALSE;
    if (!$nopre) $msg=$this->PreUpdate();
    if ($msg!='') return $msg;
    $sql = "update ".$this->dbtable." set ";
    
    
   
    $nb_keys=0;
    foreach ($this->id_fields as $k=>$v) {
      $notset[$v]="Y";
      $nb_keys++;
    }

    if (! is_array($sfields)) $fields=$this->fields;
    else {
      $fields=$sfields;
      foreach ($this->id_fields as $k=>$v) $fields[]=$v;
    }
    

    $setstr="";
    $wstr="";
    foreach ($fields as $k=>$v) {
      if (!isset($notset[$v])) {
        $setstr=$setstr." ".$v."=".$this->lw($this->$v).",";
      } else {
	$val=pg_escape_string($this->$v);
        $wstr=$wstr." ".$v."='".$val."' AND";
      } 
    }
    $setstr=substr($setstr,0,strlen($setstr)-1);
    $wstr=substr($wstr,0,strlen($wstr)-3);
    $sql.=$setstr;
    if ($nb_keys>0) {
      $sql.=" where ".$wstr.";";
    }
    
    $msg_err = $this->exec_query($sql);

    // sortie
      if ($msg_err!=''){
	return $msg_err;
      }
    
    if (!$nopost) $msg=$this->PostUpdate();
    
    if ($msg!='') return $msg;
  }	

function Delete($nopost=false)
  {
    $msg=$this->PreDelete();
    if ($msg!='') return $msg;
    $wherestr="";
    $count=0;
    
    reset($this->id_fields);
    while(list($k,$v) = each($this->id_fields)) {
      if ($count >0) {
        $wherestr=$wherestr." AND ";
      }
      $wherestr=$wherestr."( ".$v."='".AddSlashes($this->$v)."' )";
      $count++;
    }
    
    // suppression de l'enregistrement
      $sql = "delete from ".$this->dbtable." where ".$wherestr.";";
    
    $msg_err = $this->exec_query($sql);
    
    if ($msg_err!=''){
      return $msg_err;
    }
    
    if (!$nopost) $msg=$this->PostDelete();
    if ($msg!='') return $msg;
  }
/** 
 * Add several objects to the database
 * no post neither preInsert are called
 * @param bool $nopost PostInsert method not apply if true
 * @return string error message, if no error empty string
 * @see PreInsert()
 * @see PostInsert()
 */
function Adds(&$tcopy, $nopost=false)
  {
    if ($this->dbid == -1) return FALSE;
    if (! is_array($tcopy)) return FALSE;
    
    $sfields = implode(",",$this->fields);
    $sql = "copy ".$this->dbtable. "($sfields) from STDIN;\n";
    
    $trow=array();
    foreach ($tcopy as $kc=>$vc) {
      $trow[$kc]="";
      foreach($this->fields as $k=>$v) {
	$trow[$kc] .= "".((isset($vc[$v]))?$vc[$v]:$this->$v)."\t";
	//$trow[$kc][$k] .= ((isset($vc[$v]))?$vc[$v]:$this->$v);
      }
      $trow[$kc]=substr($trow[$kc],0,-1);
    }
    
    // query execution
    $berr= pg_copy_from($this->dbid,$this->dbtable,$trow,"\t");
	 
    if (! $berr) return sprintf(_("DbObj::Adds error in multiple insertion"));

    
    if (!$nopost) $msg=$this->PostInsert();
    if ($msg!='') return $msg;
  }
function lw($prop)
  {
    $result = ($prop==''?"null":"'".pg_escape_string($prop)."'");
    return $result;
  }
function CloseConnect()
  {
    pg_close("$this->dbid");
    return TRUE;
  }

function Create($nopost=false)
  {
    $msg = "";
    if (isset($this->sqlcreate)) {
      // step by step
      if (is_array($this->sqlcreate)) {
	while (list($k,$sqlquery)=each($this->sqlcreate)) {
	  $msg.=$this->exec_query($sqlquery,1);
	}
      } else {	
	$sqlcmds = explode(";",$this->sqlcreate);
	while (list($k,$sqlquery)=each($sqlcmds)) {
	  $msg.=$this->exec_query($sqlquery,1);
	}
      }
      $this->log->debug("DbObj::Create : {$this->sqlcreate}");
    }
    if (isset($this->sqlinit)) {
      $msg=$this->exec_query($this->sqlinit,1);
      $this->log->debug("Init : {$this->sqlinit}");
    }
    if ($msg != '') {
      $this->log->info("DbObj::Create $msg");   
      return $msg;
    }
    if (!$nopost) $this->PostInit();
    return($msg);
  }  

function PostInit() {
}

function init_dbid() {
  
  if ($this->dbaccess=="") {
    // don't test if file exist or must be searched in include_path 
      include("dbaccess.php");
    $this->dbaccess=getDbAccess();
    
  }
  $this->dbid= getDbid($this->dbaccess);
  return $this->dbid;
  
}
function exec_query($sql,$lvl=0)
  {
    global $SQLDELAY,$SQLDEBUG;

    if ($sql == "") return;

    if ($SQLDEBUG) $sqlt1=microtime(); // to test delay of request
    //   $mb=microtime();
    $this->init_dbid();
    $this->log->debug("exec_query : $sql");
    
    $this->res=@pg_query($this->dbid,$sql);
   

    //error_log( sprintf("<P> %s [%d]( <B>%.03f</b></p>",$sql,$this->numrows(),microtime_diff(microtime(),$mb)));
    $pgmess = pg_last_error($this->dbid);
    //    if ($pgmess != "") print "[$sql]";
    
    $this->msg_err = chop(ereg_replace("ERROR:  ","",$pgmess));
    
    
    $action_needed= "";
    if ($lvl==0) { // to avoid recursivity
      if ($this->msg_err != "") {
		     if ((eregi("Relation ['\"]([a-zA-Z_]*)['\"] does not exist",$this->msg_err) ||
			  eregi("Relation (.*) n'existe pas",$this->msg_err) ||
			  eregi("class \"([a-zA-Z_]*)\" not found",$this->msg_err)) ) {
		       $action_needed = "create";
		     } else if ((eregi("No such attribute or function '([a-zA-Z_0-9]*)'",$this->msg_err)) ||
				(eregi("Attribute ['\"]([a-zA-Z_0-9]*)['\"] not found",$this->msg_err))) {
		       $action_needed = "update";
		     } else if (eregi("relation ['\"](.*)['\"] already exists",$this->msg_err) ||
				eregi("relation (.*) existe d",$this->msg_err)){
		       $action_needed = "none";		       
		     }
		     //print "\n\t\t[".$this->msg_err."]:$action_needed\n";
{'fraction_non_alphanumeric': 0.21518504387638307, 'fraction_numerical': 0.00825500329506434, 'mean_word_length': 2.56522814393471, 'pattern_counts': {'":': 2, '<': 15, '<?xml version=': 0, '>': 297, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7195533', 'n_tokens_mistral': 10085, 'n_tokens_neox': 9735, 'n_words': 2436}