require_once(dirname(__FILE__).'/db/table.php');
require_once(dirname(__FILE__).'/db/field.php');
if (!defined('DB_HTML_FORM_BUTTONS')) define('DB_HTML_FORM_BUTTONS',''
- .'<input type="button" class="button" value="Add" onclick="this.setAttribute(\'type\',\'submit\');this.setAttribute(\'name\',\'edit\')?1:1"/>'
+ .'<input type="button" class="button" value="Add" onclick="window.location = \'?action=edit&table=\'+this.parentElement.elements[\'table\'].value"/>'
+ #.'<input type="button" class="button" value="Add" onclick="this.setAttribute(\'type\',\'submit\');this.setAttribute(\'name\',\'edit\')?1:1"/>'
#.'<input type="button" class="button" value="Add" onclick="this.setAttribute(\'name\',\'edit\');this.parentElement.submit()?0:0"/>'
#.'<input type="button" class="button" onclick="return nb.form_clear(this.parentElement)" value="X"/>'
.'<a class="button" href="#" onclick="nb.form_clear(this.parentElement)?0:0">X</a>'
function database() {
$rows = $this->db->query('PRAGMA database_list');
}
+
+ function execParams($sql,$params) {
+
+ try {
+ $r = $this->conn->execParams($sql, $params);
+ } catch (PDOException $e) {
+ err(join(': ',array($e->getMessage(),"Db.execParam()",$sql)));
+ $r = null;
+ }
+
+ return $r;
+ }
*/
- function exec($sql) {
- return $this->conn->exec($sql);
+ function exec($sql,$params=null) {
+
+ try {
+ $r = $this->conn->exec($sql,$params);
+ /*
+ if ($params === null) {
+ $r = $this->conn->exec($sql,$params);
+ } else {
+ $r = $this->conn->exec($sql);
+ }
+ */
+ } catch (PDOException $e) {
+ err(join(': ',array($e->getMessage(),"Db.exec()",$sql)));
+ $r = null;
+ }
+
+ return $r;
}
function query($sql) {
try {
$r = $this->conn->query($sql);
} catch (PDOException $e) {
- err(array("Db.query()",$e->getMessage(),$sql));
+ err(join(': ',array($e->getMessage(),"Db.query()",$sql)));
$r = null;
}
return join($sep,$query->fetch(PDO::FETCH_NUM));
}
+ /*
function query2a($sql) {
$r = $this->conn->query($sql,PDO::FETCH_COLUMN);
return $r ? $r->fetch() : $r;
return $this->conn->query($sql,PDO::FETCH_ASSOC);
}
+ */
function quote($v) {
return $this->conn->quote($v);
}
function html_menu($table=null) {
$html = ' onchange="this.parentElement.submit()"';
- $r = '<form class="db menu" method="get" action="">'.PHP_EOL;
-
- if (!empty($table)) {
- foreach ( array_keys($table->fields()) as $k ) {
+ $r = '<form class="db menu" method="get" action="" onsubmit="return nb.form_submit_clean(this)">'.PHP_EOL;
- $v = $this->p($k);
-
- $r .= ''
- .'<span class="i">'
- . '<label>'.prettyText($k)
- .'</label>'
- . '<input type="text" id="'.$k.'" name="'.$k.'" value="'.$v.'" />'
- .'</span>'
- ;
-
- }
- #$r .= '<span class=""></span>';
- $r .= '<hr/>';
- }
-
- /// Tables
+ // Tables
$r .= '<label>Tables</label>'.html_select_array($this->tables(),array(
- 'html' => 'class="tables" name="table"'.$html,
+ 'html' => 'class="tables" name="table"'.preg_replace('/"/','"nb.form_clear(this.parentElement);',$html,1),
'selected' => $this->p('table'),
'prettyText' => true,
));
'prettyText' => true,
));
- // Bye
+ // Buttons
$r .= DB_HTML_FORM_BUTTONS;
+
+ // Criterias
+ if (!empty($table)) {
+ $r .= '<div class="criterias">';
+ foreach ( array_keys($table->fields()) as $k ) {
+
+ $v = $this->p($k);
+
+ $r .= ''
+ #.'<span class="i">'
+ . '<label>'.prettyText($k)
+ .'</label>'
+ . '<input type="text" id="'.$k.'" name="'.$k.'" value="'.$v.'" />'
+ #.'</span>'
+ ;
+
+ }
+ $r .= '</div>';
+ #$r .= '<span class=""></span>';
+ }
+
+ // Bye
$r .= '</form>'.PHP_EOL;
return $r;
}
return isset($_REQUEST[$name]) ? $_REQUEST[$name] : $default;
}
+ function sql_name($value) {
+ if (preg_match('/^\w+$/',$value)) return $value;
+ if ($this->db->type == 'mysql') return '`'.$value.'`';
+ return '"'.$value.'"';
+ }
+
}
?>
<?php
-$DB_FIELD_CONN = isset($Db) ? $Db->conn : null;
+/*
+$DB_FIELD_TYPES = array(
+ 'bool' => PDO::PARAM_BOOL,
+ #'null' => PDO::PARAM_NULL,
+ 'int' => PDO::PARAM_INT,
+ 'str' => PDO::PARAM_STR,
+ 'blob' => PDO::PARAM_LOB,
+);
+*/
class field {
public $name;
public $type = 'text';
public $default = null;
+ private $autoincrement = false;
public $key = false;
- public $autoinc = false;
+ public $table = null;
- function __construct($name,$attr=array()) {
- $this->name = $name;
+ function __construct($attr=array()) {
foreach ($attr as $k => $v) { $this->$k = $v; }
}
- function is_num() {
- return preg_match('/int|float|number|currency/',$this->type) ? 1 : 0;
+ function autoincrement() {
+ return $this->autoincrement;
+ }
+
+ function numeric() {
+ return preg_match('/int|float|number|currency/',$this->type) ? true : false;
}
function html_edit($value) {
- return '<label for="'.$this->name.'">'.htmlspecialchars($this->name).'</label>'
+ return '<label for="'.$this->name.'">'.htmlspecialchars(prettyText($this->name)).'</label>'
.'<input name="'.$this->name.'" id="'.$this->name.'" value="'.htmlspecialchars($value).'" />'
.PHP_EOL;
}
+ function db() {
+ global $Db;
+ return ( isset($Db) ? $Db : null );
+ }
+
+ function sql_name() {
+ return $this->db()->sql_name($this->name);
+ }
+
function quote($value,$force_quote=false) {
- if ($DB_FIELD_CONN === null) return "'".str_replace("'","\\'",$value)."'";
- return $DB_FIELD_CONN->quote($value);
+ if ($force_quote or !$this->numeric()) {
-// TODEL - NB 08.07.15
- if ($force_quote or !$field->is_num()) {
+ if (($db = $this->db()) === null) return "'".preg_replace("/'/","\\'",$value)."'";
+ return $db->quote($value);
+ } else {
- if ($DB_FIELD_CONN === null) return "'".preg_replace("/'/","\\'",$value)."'";
- return $DB_FIELD_CONN->quote($value);
+ if (strcmp($value,'') == 0) $value = 'NULL';
}
return $value;
}
- function where($value) {
+ function size() {
+ return preg_match('/\((\d+)\)/',$this->type,$m) ? $m[1] : null;
+ }
+ function where($values) {
// No empty value
$v = isset($value) ? $value : null;
if (strcmp($v,'')==0
) return null;
// NB 03.07.15 $number = preg_match('/int|float|number|currency/',$this->type) ? 1 : 0;
- $number = $this->is_num();
+ $number = $this->numeric();
// Equal / Not Equal
$equal = '=';
// Regex
if (strpos($v,'~')===0) {
- return $this->name . ($not ? 'NOT ' : '').'REGEXP ' . $DB_FIELD_CONN->quote( substr($v,1) );
+ return $this->name . ($not ? 'NOT ' : '').'REGEXP ' . $this->db()->quote( substr($v,1) );
}
// Text
if (!$this->num() or !preg_match('/^\d+(\.\d*)?$/',$v)) { # text criteria value
if (strtolower($v)=='null') $v = '';
- return $this->name.' '.($not ? 'NOT ' : '').'LIKE '.$DB_FIELD_CONN->quote(str_replace('*','%',$v));
+ return $this->name.' '.($not ? 'NOT ' : '').'LIKE '.$this->db()->quote(str_replace('*','%',$v));
// Others
} else {
// Date, Time
} else {
- $v = $DB_FIELD_CONN->quote($v);
+ $v = $this->db()->quote($v);
}
$equal = $not ? '<>' : '=';
return "$k$equal$v";
}
+ function pdo_type() {
+ if ($this->numeric) return PDO::PARAM_INT;
+ if (strpos($this->type,'bool') !== false ) return PDO::PARAM_BOOL;
+ if (strpos($this->type,'blob') !== false ) return PDO::PARAM_LOB; # not a bug LOB
+ return PDO::PARAM_STR;
+ }
+
+ function bindParam($sth,$value) {
+ # See: http://php.net/manual/en/pdostatement.bindparam.php
+ $sth->bindParam(':'.$this->name, $value, PDO::PARAM_INT);
+ $sth->bindParam(':'.$this->name, $value, PDO::PARAM_STR);
+ $sth->bindParam(':calories', $calories, PDO::PARAM_INT);
+ }
+
}
?>
<?php
require_once(dirname(__FILE__).'/../functions.php');
require_once(dirname(__FILE__).'/../db.php');
+require_once(dirname(__FILE__).'/../db/field.php');
if (false and empty($_SERVER['DOCUMENT_ROOT'])) {
$_REQUEST['db'] = 'rent'; $name = 'tenant';
foreach ($rows as $row) {
- $this->fields[$row['name']] = array(
+ $field = array(
+ 'name' => null,
'extra' => null,
'type' => null,
'default' => null,
'key' => null,
- 'autoincrement' => false,
+ 'autoincrement' => null,
);
- $this->fields[$row['name']]['type'] = strtolower($row['type']);
+ $field['name'] = $row['name'];
+ $field['type'] = strtolower($row['type']);
if (isset($row['notnull'])) {
- $this->fields[$row['name']]['null'] = $row['notnull'] == '0' ? 1 : 0;
+ $field['null'] = $row['notnull'] == '0' ? 1 : 0;
} else {
- $this->fields[$row['name']]['null'] = preg_match('/^1|yes|t/i',$row['null']) ? 1 : 0;
+ $field['null'] = preg_match('/^1|yes|t/i',$row['null']) ? true : false;
}
- # sqlite autoincrement
- if ($this->db->type == 'sqlite' and preg_match('/[\(,]'.$row['name'].' [^\),]+ AUTOINCREMENT/',$this->sql())) {
- $this->fields[$row['name']]['autoincrement'] = true;
- }
+ # Autoincrement
# mysql autoincrement
if (isset($row['Extra']) and $row['Extra'] == 'auto_increment') {
- $this->fields[$row['name']]['autoincrement'] = true;
+ $field['autoincrement'] = true;
+
+ # sqlite autoincrement
+ } elseif ($this->db->type == 'sqlite'
+ and preg_match('/[\(,]'.$row['name'].' [^\),]+ AUTOINCREMENT/',$this->sql())
+ ) {
+ $field['autoincrement'] = true;
+
}
# Postgres autoincrement / default
if (isset($row['pg_default'])) {
if (preg_match('/^nextval\(/',$row['pg_default'])) {
- $this->fields[$row['name']]['autoincrement'] = true;
+ $field['autoincrement'] = true;
} elseif (preg_match("/^''/",$row['pg_default'])) {
- $this->fields[$row['name']]['default'] = '';
+ $field['default'] = '';
} else {
- $this->fields[$row['name']]['default'] = $row['pg_default'];
+ $field['default'] = $row['pg_default'];
}
}
# sqlite default
foreach (array('dflt_value') as $f) {
if (!isset($row[$f])) continue;
- $this->fields[$row['name']]['default'] = $row[$f];
+ $field['default'] = $row[$f];
}
foreach (array('pk','Key') as $f) {
if (!isset($row[$f])) continue;
- $this->fields[$row['name']]['key'] = preg_match('/^1|yes|t/i',$row[$f]) ? 1 : 0;
+ $field['key'] = preg_match('/^1|yes|t/i',$row[$f]) ? 1 : 0;
}
+ $this->fields[$row['name']] = new field($field);
+
}
}
$keys = $this->fields_keys($others);
if (empty($keys)) $keys = $others;
- foreach ($keys as $name => $spec) {
+ foreach ($keys as $name => $field) {
if (isset($values[$name]) and strcmp($values[$name],'')!=0)
$url[] = $name . '=' .urlencode($values[$name])
;
function fields_keys(&$others=array()) {
- #if (!$this->fields_keys) {
- $this->fields_keys = array();
+ $fields_keys = array();
- foreach ($this->fields() as $name => $f) {
- #debug($f);
- if ((int)$f['key'] == 1) {
- $this->fields_keys[$name] = $f;
- } else {
- $others[$name] = $f;
- }
+ foreach ($this->fields() as $name => $f) {
+ if ($f->key) {
+ $fields_keys[$name] = $f;
+ } else {
+ $others[$name] = $f;
}
+ }
- #}
-
- return $this->fields_keys;
+ return $fields_keys;
}
if (!is_array($values)) $values = array($values);
$add = false;
- $where = str_replace(' LIKE ','=',$this->where_criterias($values));
+ #$where = str_replace(' LIKE ','=',$this->where_criterias($values));
+ $where = $this->where($this->fields(),$values);
if (empty($where)) {
$where = ' WHERE 1=0';
$add = true;
+ } else {
+ $where .= " LIMIT 1";
}
$sql = "SELECT *" . $this->select_extras();
$sql .= " FROM ".$this->sql_name().$where;
- $sql .= " LIMIT 1";
$this->sql = $sql;
$this->debug($sql,1);
$st = $this->db->conn->prepare($sql);
$st->execute();
- echo '<form class="db edit" method="post" action="">'.PHP_EOL;
+ echo '<form class="db edit" method="post" action="?">'.PHP_EOL;
+ echo '<div class="fields">'.PHP_EOL;
$count = 0;
- if ($row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT) or $add) {
+ if ( $add or ($row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT))) {
$count ++;
- foreach ($this->fields() as $name => $attr) {
- $field = new field($name,$attr);
- echo $field->html_edit( (is_array($row) and array_key_exists($name,$row) ) ? $row[$name] : $attr['default']);
- unset($field);
+ foreach ($this->fields() as $name => $field) {
+ echo $field->html_edit(
+ (! $add and array_key_exists($name,$row) ) ? $row[$name] : $field->default
+ );
}
+
}
+ echo '</div>'.PHP_EOL;
echo ''
.'<div class="db buttons">'
- .'<input type="submit" name="update"/>'
+ .'<input type="submit"/>'
.'<input type="hidden" name="table" value="'.$this->db->p('table').'"/>'
+ .'<input type="hidden" name="action" value="'.($add ? 'insert' : 'update').'"/>'
.'<input type="reset" />'
.( empty($_SERVER['HTTP_REFERER']) ? '' : '<input type="button" onclick="document.location=document.referrer" value="Cancel" />')
.'</div>'.PHP_EOL
}
+ function where($fields,$hvalues,$need_all_values=false) {
+
+ // Construct where
+ $where = array();
+ foreach ($fields as $k => $field) {
+ if (!isset($hvalues[$k])) {
+ if ($need_all_values) return null;
+ continue;
+ }
+ $where[] = $field->sql_name() . '=' . $field->quote($hvalues[$k]);
+ }
+ #var_dump($where); exit;
+ #.' VALUES (' . join(',',ar_map('":$a"',$fields)).')'
+
+ return empty($where) ? '' : ' WHERE ' . join(' AND ',$where);
+
+ }
+
function where_criterias($values,$logic='') {
$having = $where = array();
if (empty($logic)) $logic = 'AND';
- foreach ($this->fields() as $k => $spec) {
+ foreach ($this->fields() as $k => $field) {
// No empty values
$v = isset($values[$k]) ? $values[$k] : null;
if (strcmp($v,'')==0 or $v=='!' or $v=='~') continue;
-// NB 03.07.15 $number = preg_match('/int|float|number|currency/',$spec['type']) ? 1 : 0;
- $field = new field($k,$spec);
- $number = $field->is_num();
+ $number = $field->numeric();
// Equal / Not Equal
$equal = '=';
// Regex
if (strpos($v,'~')===0) {
$v = substr($v,1);
- $v = $this->db->conn->quote($v);
+ $v = $this->db->quote($v);
$equal = ' '.($not ? 'NOT ' : '').'REGEXP ';
// Text
- } elseif (preg_match('/text|char|blob/',$spec['type'])
+ } elseif (preg_match('/text|char|blob/',$field->type)
or !preg_match('/^\d+(\.\d*)?$/',$v) # text criteria value
) {
// * -> %
$v = str_replace('*','%',$v);
- $v = $this->db->conn->quote($v);
+ $v = $this->db->quote($v);
$equal = ' '.($not ? 'NOT ' : '').'LIKE ';
// Others
// Date, Time
} else {
- $v = $this->db->conn->quote($v);
+ $v = $this->db->quote($v);
}
$equal = $not ? '<>' : '=';
}
if (preg_match('/(LIKE|REGEXP) ..$/',"$equal$v")) {
- $k = "COALESCE($k,".$this->db->conn->quote('').")";
+ $k = "COALESCE($k,".$this->db->quote('').")";
}
- if ($this->db->type == 'mysql' and $spec['extra']) {
+ if ($this->db->type == 'mysql' and $field->extra) {
$having[] = "$k$equal$v";
- } elseif ($this->db->type == 'pgsql' and $spec['extra']) {
+ } elseif ($this->db->type == 'pgsql' and $field->extra) {
$where[] = $this->extras[$k]."$equal$v";
} else {
$where[] = "$k$equal$v";
}
- unset($field);
} #foreach fields
$sql = '';
$select[] = "$v AS ".($this->db->type == 'pgsql'
? '"'.str_replace('"','\"',$k).'"'
- : $this->db->conn->quote($k)
+ : $this->db->quote($k)
);
/*
- $select[] = "$v AS ".$this->db->conn->quote($k);
+ $select[] = "$v AS ".$this->db->quote($k);
*/
/*
- $k = $this->db->conn->quote($k);
+ $k = $this->db->quote($k);
if ($this->db->type == 'pgsqpl') $k = str_replace(
$select[] = "$v AS $k"
*/
$sql = "SELECT *" . $this->select_extras();
$sql .= " FROM $this->name".$this->where_criterias($this->db->p(),$this->db->p('op'));
$this->sql = $sql;
- #$this->debug($sql);
$this->debug($sql,1);
//
$count++;
$count_fields = 0;
- foreach ($this->fields() as $f => $spec) {
+ foreach ($this->fields() as $f => $field) {
- if (!$spec['extra']) {
+ if (!$field->extra) {
if ($escape) $row[$f] = htmlspecialchars($row[$f]);
}
- if ($this->db->type == 'sqlite' and preg_match('/^float\((?:\d+,)?(\d+)\)/',$spec['type'],$m)) {
+ if ($this->db->type == 'sqlite' and preg_match('/^float\((?:\d+,)?(\d+)\)/',$field->type,$m)) {
$row[$f] = sprintf('%.'.$m[1].'f',$row[$f]);
}
}
if ($opt['is_html']) {
- array_unshift($row,'<a class="edit button" href="'.$this->url_keys($row,'edit=1').'">'.DB_HTML_EDIT.'</a>');
- array_push($row,'<a class="delete button" href="'.$this->url_keys($row,'delete=1').'">'.DB_HTML_DELETE.'</a>');
+ array_unshift($row,'<a class="edit button" href="'.$this->url_keys($row,'action=edit').'">'.DB_HTML_EDIT.'</a>');
+ array_push($row,'<a class="delete button" href="'.$this->url_keys($row,'action=delete').'">'.DB_HTML_DELETE.'</a>');
}
echo $this->{"rows_rec_$format"}($row);
}
function sql_name() {
- if ($this->db->type == 'mysql') return '`'.$this->name.'`';
- return $this->name;
+ return $this->db->sql_name($this->name);
+ }
+
+ function insert($hvalues) {
+ $names = $values = array();
+ #var_dump($hvalues);
+ foreach ($this->fields() as $name => $field) {
+ if (!isset($hvalues[$name])) continue;
+ if ($field->key and $field->autoincrement()) continue;
+ $names[] = $field->sql_name();
+ #$values[] = $field->quote($hvalues[$name]);
+ $values[] = $hvalues[$name];
+ }
+ #bye($values);
+
+ $sql =
+ 'INSERT INTO '. $this->sql_name() . ' (' . join(',',$names).')'
+ #.' VALUES (' . join(',',$values).')'
+ .' VALUES (' . join(',',ar_map('"?"',$values)) . ')'
+ ;
+ bye(array($sql,$values));
+
+ return $this->db->exec($sql,$values);
+ return $this->db->exec($sql);
}
function update($hvalues) {
- $keys = $this->fields_keys($values);
- $values = array_keys($values);
- $keys = $keys ? array_keys($keys) : $values;
- $fields = array_keys($this->fields());
- #bye($keys);
+ $keys = array();
+ $keys_values = array();
+ $fields = array();
+ $fields_values = array();
+ $values = array();
- $sql =
- ($this->db->type == 'mysql' ? 'REPLACE' : 'REPLACE')
- .' INTO ' . $this->sql_name() . ' (' . join(',',$fields).')'
- .' VALUES (' . join(',',ar_map('":$a"',$fields)).')'
- #.' WHERE ' . join(' AND ',ar_map('"$a=:$a"',$keys))
- ;
- $_sql = ''
+ foreach ($this->fields() as $name => $field) {
+
+ if (!isset($hvalues[$name])) continue;
+ $value = $hvalues[$name];
+
+ if ($field->key) {
+ $keys[] = $name;
+ $keys_values[] = $name;
+
+ } else {
+ $fields[] = $name;
+ $fields_values[] = $name;
+
+ }
+
+ }
+
+ if (empty($keys)) {
+ $keys = $fields;
+ $keys_values = $fields_values;
+ }
+
+ $sql = ''
.'UPDATE ' . $this->sql_name()
- .' SET ' . join(',',ar_map('"$a=:$a"',$values))
- .' WHERE ' . join(' AND ',ar_map('"$a=:$a"',$keys))
+ .' SET ' . join(',',ar_map('"$a=:$a"',$fields))
+ .' WHERE ' . join(' AND ',ar_map('"$a=:key_$a"',$keys))
;
- debug($sql);
- $query = $this->db->conn->prepare($sql);
- if (!$query) return err('PDO::errorInfo(): ' .join(' ', $this->db->conn->errorInfo()) .PHP_EOL);
+
+ #bye($sql);
+ $this->debug($sql,1);
+
+ if (!($query = $this->db->conn->prepare($sql))) {
+ err('PDO::errorInfo(): ' .join(' ', $this->db->conn->errorInfo()) .PHP_EOL);
+ return false;
+ }
- #print_r(array_keys($this->fields()));
- #debug($hvalues);
- foreach (array_keys($this->fields()) as $k) {
- #echo "== $k=".$hvalues[$k].'</br>'.PHP_EOL;
- $query->bindParam(":$k", $hvalues[$k]);
+ foreach ($fields as $name) {
+ $query->bindParam(":$name", $hvalues[$name]);
+ }
+ foreach ($keys as $name) {
+ $query->bindParam(":key_$name", $hvalues[$name]);
}
#return $sql;
- $execute = $query->execute();
- if (!$execute) return err('PDO::errorInfo(): ' .join(' ', $this->db->conn->errorInfo()) .PHP_EOL);
- debug($execute);
+ if (!($execute = $query->execute())) {
+ err('PDO::errorInfo(): ' .join(' ', $this->db->conn->errorInfo()) .PHP_EOL);
+ return false;
+ }
+
+ return $execute;
}
- function delete($hvalues) {
- $where = str_replace(' LIKE ','=',$this->where_criterias($hvalues));
- if (!$where) return 0;
- $sql = 'DELETE FROM ' . $this->sql_name() . $where;
- debug($sql);
- try {
- $this->db->conn->query($sql);
- } catch (PDOException $e) {
- return err($e->getMessage(), "Table.delete()");
+ function delete($hvalues,&$e=null) {
+ $keys = $this->fields_keys();
+ // If no primary keys, we use all field
+ if (empty($keys)) $keys = $this->fields();
+
+ if (!($where = $this->where($keys,$hvalues,true))) {
+ err('Db.delete(): Missing keys values');
+ return null;
}
- return true;
+
+ $sql = 'DELETE FROM ' . $this->sql_name() . $where;
+ return $this->db->exec($sql);
}
}