From 20cacc2f1df0167466fc4f5d2a449d814b33bf88 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Fri, 8 Apr 2005 18:30:32 +0000 Subject: [PATCH] 1) fixed not working inserts, if primary key (not auto-increment) where given 2) allow 0 to be written and not treated as null 3) added join feature for search --- etemplate/inc/class.so_sql.inc.php | 90 ++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 24 deletions(-) diff --git a/etemplate/inc/class.so_sql.inc.php b/etemplate/inc/class.so_sql.inc.php index caee32d4b8..b7b0c15289 100644 --- a/etemplate/inc/class.so_sql.inc.php +++ b/etemplate/inc/class.so_sql.inc.php @@ -23,7 +23,7 @@ * @package etemplate * @subpackage contrib * @author RalfBecker-AT-outdoor-training.de - * @license GPL + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License */ class so_sql { @@ -155,6 +155,8 @@ class so_sql */ function data_merge($new) { + if ($this->debug) echo "

so_sql::data_merge(".print_r($new).")

\n"; + if (!is_array($new) || !count($new)) { return; @@ -173,6 +175,7 @@ class so_sql $this->data[$col] = $new[$col]; } } + if ($this->debug) _debug_array($this->data); } /** @@ -307,13 +310,15 @@ class so_sql $this->data2db(); + //echo "so_sql::save(".print_r($keys,true).") autoinc_id='$this->autoinc_id', data="; _debug_array($this->data); + if ($this->autoinc_id && !$this->data[$this->db_key_cols[$this->autoinc_id]]) // insert { foreach($this->db_cols as $db_col => $col) { if (!$this->autoinc_id || $db_col != $this->autoinc_id) // not write auto-inc-id { - $data[$db_col] = $this->data[$col] == '' && $this->empty_on_write == 'NULL' ? null : $this->data[$col]; + $data[$db_col] = (string) $this->data[$col] === '' && $this->empty_on_write == 'NULL' ? null : $this->data[$col]; } } $this->db->insert($this->table_name,$data,false,__LINE__,__FILE__); @@ -327,18 +332,25 @@ class so_sql { foreach($this->db_data_cols as $db_col => $col) { - $data[$db_col] = $this->data[$col] == '' && $this->empty_on_write == 'NULL' ? null : $this->data[$col]; + $data[$db_col] = (string) $this->data[$col] === '' && $this->empty_on_write == 'NULL' ? null : $this->data[$col]; } $keys = ''; foreach($this->db_key_cols as $db_col => $col) { $keys[$db_col] = $this->data[$col]; } - $this->db->update($this->table_name,$data,$keys,__LINE__,__FILE__); + if (!$this->autoinc_id) // always try an insert if we have no autoinc_id, as we dont know if the data exists + { + $this->db->insert($this->table_name,$data,$keys,__LINE__,__FILE__); + } + else + { + $this->db->update($this->table_name,$data,$keys,__LINE__,__FILE__); + } } $this->db2data(); - return $this->db->errno; + return $this->db->Errno; } /** @@ -390,9 +402,11 @@ class so_sql * @param string $op defaults to 'AND', can be set to 'OR' too, then criteria's are OR'ed together * @param int/boolean $start if != false, return only maxmatch rows begining with start * @param array $filter if set (!=null) col-data pairs, to be and-ed (!) into the query without wildcards + * @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or + * "LEFT JOIN table2 ON (x=y)", Note: there's no quoting done on $join! * @return array of matching rows (the row is an array of the cols) or False */ - function search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null) + function search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='') { if (!is_array($criteria)) { @@ -403,17 +417,23 @@ class so_sql $criteria = $this->data2db($criteria); foreach($this->db_cols as $db_col => $col) - { //echo "testing col='$col', criteria[$col]='".$criteria[$col]."'
"; + { + //echo "testing col='$col', criteria[$col]='".print_r($criteria[$col],true)."'
"; if (isset($filter[$col]) && $filter[$col]) continue; // added later if (isset($criteria[$col]) && ($empty || $criteria[$col] != '')) { - $query .= ($query ? " $op " : '') . $db_col . - ($wildcard || strstr($criteria[$col],'*') || strstr($criteria[$col],'?') ? - ' LIKE '.$this->db->quote($wildcard.strtr(str_replace('_','\\_',$criteria[$col]),'*?','%_').$wildcard) : - "=".$this->db->quote($criteria[$col])); + if ($wildcard || strstr($criteria[$col],'*') || strstr($criteria[$col],'?')) + { + $query[] = $db_col.' LIKE '.$this->db->quote($wildcard.str_replace(array('%','_','*','?'),array('\\%','\\_','%','_'),$criteria[$col]).$wildcard); + } + else + { + $query[$db_col] = $criteria[$col]; + } } } + if (is_array($query) && $op != 'AND') $query = $this->db->column_data_implode(' '.$op.' ',$query); } if (is_array($filter)) { @@ -428,28 +448,49 @@ class so_sql { if ($val !== '') $db_filter[array_search($col,$this->db_cols)] = $val; } - if ($query) $db_filter[] = '('.$query.')'; + if ($query) + { + if ($op != 'AND') + { + $db_filter[] = '('.$this->db->column_data_implode(' '.$op.' ',$query).')'; + } + else + { + $db_filter = array_merge($db_filter,$query); + } + } $query = $db_filter; } if ($start !== false) // need to get the total too, saved in $this->total { - $this->db->select($this->table_name,'COUNT(*)',$query,__LINE__,__FILE__); + $this->db->select($this->table_name,'COUNT(*)',$query,__LINE__,__FILE__,0,'',false,0,$join); $this->total = $this->db->next_record() ? (int) $this->db->f(0) : false; } - $cols = $only_keys === true ? $this->db_key_cols : (!$only_keys ? $this->db_cols : explode(',',str_replace('DISTINCT ','',$only_keys))); - $this->db->select($this->table_name,($only_keys === true ? implode(',',$this->db_key_cols) : (!$only_keys ? '*' : $only_keys)). ($extra_cols ? ','.(is_array($extra_cols) ? implode(',',$extra_cols) : $extra_cols) : ''), - $query,__LINE__,__FILE__,$start,$order_by ? 'ORDER BY '.$order_by : ''); + $query,__LINE__,__FILE__,$start,$order_by ? 'ORDER BY '.$order_by : '',false,0,$join); if ($this->debug) { echo "

so_sql::search(,only_keys=$only_keys,order_by='$order_by',wildcard='$wildcard',empty=$empty,$op,start='$start',".print_r($filter,true).") query=".print_r($query,true).", total='$this->total'

\n"; echo "
criteria = "; _debug_array($criteria); } - $arr = array(); - $cols = $only_keys === true ? $this->db_key_cols : (!$only_keys ? $this->db_cols : explode(',',str_replace('DISTINCT ','',$only_keys))); - if ($extra_cols) + if ($only_keys == true) // only primary key + { + $cols = $this->db_key_cols; + } + elseif (!$only_keys) // all columns + { + $cols = $this->db_cols; + } + else // only the specified columns + { + foreach(explode(',',str_replace('DISTINCT ','',$only_keys)) as $col) + { + $cols[$col] = $col; + } + } + if ($extra_cols) // extra columns to report { foreach(is_array($extra_cols) ? $extra_cols : array($extra_cols) as $col) { @@ -457,14 +498,15 @@ class so_sql $cols[$col] = $col; } } - for ($n = 0; $this->db->next_record(); ++$n) + $arr = array(); + for ($n = 0; ($row = $this->db->row(true)); ++$n) { - $row = array(); + $data = array(); foreach($cols as $db_col => $col) { - $row[$col] = $this->db->f($db_col); + $data[$col] = $row[$db_col]; } - $arr[] = $this->db2data($row); + $arr[] = $this->db2data($data); } return $n ? $arr : False; } @@ -516,7 +558,7 @@ class so_sql { foreach($this->db_key_cols as $db_key_col => $key_col) { - if ($data[$key_col] != $other[$key_col]) + if ($data[$key_col] != $other[$key_col]) { if ($this->debug) {