]> git.nbdom.net Git - nb.git/commitdiff
Bed
authorNicolas Boisselier <nicolas.boisselier@gmail.com>
Tue, 5 Apr 2016 00:03:54 +0000 (01:03 +0100)
committerNicolas Boisselier <nicolas.boisselier@gmail.com>
Tue, 5 Apr 2016 00:03:54 +0000 (01:03 +0100)
lib/php/db.php
lib/php/db/field.php
lib/php/db/table.php
lib/php/db/types.php [deleted file]
lib/php/functions.php

index 2b1c58e4856a38795c68ae5b0fe695f8742da574..cf32676caef5526279dd746bc3465470a489b9ad 100644 (file)
@@ -9,8 +9,8 @@
 require_once(dirname(__FILE__).'/nb.php');
 require_once(dirname(__FILE__).'/out.php');
 require_once(dirname(__FILE__).'/db/table.php');
-$DB_TYPES = array();
-# NB 29.03.16 require_once(dirname(__FILE__).'/db/types.php');
+require_once(dirname(__FILE__).'/db/field.php');
+$DB_TYPES = array(); # See db/types/*.php
 
 class Db extends nb {
 
@@ -206,7 +206,7 @@ class Db extends nb {
     return $r;
   }
 
-  function query($sql) {
+  public function query($sql) {
   # See: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers
 
     try {
@@ -220,7 +220,7 @@ class Db extends nb {
 
   }
 
-  function row($sql,$sep=' ') {
+  public function row($sql,$sep=' ') {
     $query = $this->query($sql);
     $result = $query->fetch(PDO::FETCH_NUM);
     if (!is_array($result)) return $result;
@@ -476,7 +476,6 @@ EOF;
             array('db.help','This help'),
             array('[db.]dbs','List databases'),
             array('[db.]tables','List tables'),
-            array('[db.]html_menu','Html menu for tables with links'),
 
             array('[table.]rows','Dump one table, use format='),
             array('[table.]fields','List fields'),
@@ -499,11 +498,6 @@ EOF;
         } elseif ($action == 'db.dbs' or $action == 'dbs') {
           $return = $this->out2($this->dbs,"name");
 
-        } elseif ($action == 'db.html_menu' or $action == 'html_menu') {
-          $this->print_header($this->p('format','html'));
-          echo $this->html_menu();
-          $return = true;
-
         } elseif (preg_match('/^db\.(\w+)/',$action,$m)) {
           if ($rows = $this->$m[1]()) $return = $this->out2($rows,(is_scalar($rows) ? $m[1] : array()));
 
@@ -705,6 +699,33 @@ EOF;
       #'dbs' => join(' ',array_values($this->dbs)),
     )+$status;
   }
+
+  public function fields($st) {
+    # See: http://php.net/manual/en/pdostatement.getcolumnmeta.php
+    $fields = array();
+    for ($i = 0; $i < $st->columnCount(); $i++) {
+      $col = $st->getColumnMeta($i);
+
+      $f = new Field();
+      $col['type'] = $f->pdo2type($col['pdo_type']);
+      unset($col['pdo_type']);
+
+      if (!empty($col['flags'])) {
+        $col['null'] = in_array('not_null',$col['flags']) ? false : true;
+        $col['key'] = in_array('primary_key',$col['flags']) ? true : false;
+      }
+      unset($col['flags']);
+
+      unset($col['len']); # never right !
+      unset($col['precision']); # ???
+
+      $f->__construct($col);
+      $fields[] = $f;
+    }
+
+    return $fields;
+  }
+
 } # < Class
 
 ?>
index c83b61af06bc899e1c0643d211b329d0558484bd..15d8cf9fd3fd52be625eafd7970544928b8aa08a 100644 (file)
@@ -9,15 +9,14 @@ $DB_FIELD_TYPES = array(
 );
 */
 class field {
-  private $table = null;
-
+  private $table;
   public $name;
   public $type = 'text';
-  public $null = false;
+  public $null = true;
   public $key = false;
-  public $default = null;
+  public $default;
   public $autoincrement = false;
-  public $extra = null;
+  public $extra;
 
   public function __sleep() { return array(
     'name',
@@ -137,7 +136,7 @@ class field {
   # - NB 25.03.16
   * Return the value quoted
   public function sql($v) {
-    $type = $this->pdo_type($this->type);
+    $type = $this->type2pdo($this->type);
     if ($type === PDO::PARAM_NULL) {
       return 'NULL';
     } elseif ($type === PDO::PARAM_INT) {
@@ -150,7 +149,15 @@ class field {
   }
   */
 
-  public function pdo_type() {
+  public static function pdo2type($pdo) {
+    if ($pdo === PDO::PARAM_BOOL) return 'bool';
+    if ($pdo === PDO::PARAM_LOB) return 'blob';
+    if ($pdo === PDO::PARAM_INT) return 'int';
+    if ($pdo === PDO::PARAM_STR) return 'varchar';
+    self::bye("Unknow pdo type: `$pdo`");
+  }
+
+  public function type2pdo() {
     if (func_get_args()>0 and func_get_arg(0) === null) return PDO::PARAM_NULL;
     if ($this->numeric()) return PDO::PARAM_INT;
     if (strpos($this->type,'bool') !== false ) return PDO::PARAM_BOOL;
@@ -162,8 +169,8 @@ class field {
     # See: http://php.net/manual/en/pdostatement.bindparam.php
     if ($name === null) $name = ':'.$this->name;
 #debug($this->name . " | $name | $value | $this->type | " .  $this->size()."<br/>");
-    return $sth->bindParam($name, $value, $this->pdo_type($value), $this->size());
-// NB 27.07.15     return $sth->bindParam($name, $value, $this->pdo_type($value));
+    return $sth->bindParam($name, $value, $this->type2pdo($value), $this->size());
+// NB 27.07.15     return $sth->bindParam($name, $value, $this->type2pdo($value));
   }
 
   public function out($value,$html_escape=false) {
index 1fc26d67589c99392db03798b0dc1d1f41020763..6563da3a075262f8f5ec376e1472cc5bf0382825 100644 (file)
@@ -82,7 +82,7 @@ Class Table extends nb {
     foreach ($opt as $k => $v) { $this->$k = $v; }
 
     // Name, could be a select
-    if (stripos($this->name,'SELECT ')===0) {
+    if (0 and stripos($this->name,'SELECT ')===0) {
       #$temp = '_'.substr(md5($this->name),0,6);
       $temp = DB_TABLE_QUERY_NAME;
       #bye("CREATE TEMPORARY VIEW $temp AS $this->name");
@@ -257,7 +257,6 @@ Class Table extends nb {
     if (!is_array($values)) $values = array($values);
 
     $add = false;
-    #$where = str_replace(' LIKE ','=',$this->where_criterias($values));
     $where = $this->where($this->fields(),$values);
     if (empty($where)) {
       $where = ' WHERE 1=0';
@@ -547,21 +546,28 @@ Class Table extends nb {
     //
     // Select
     //
-    $where = $this->where_criterias($this->p(),$this->p('op'));
-    $select_count = ( $where ? $this->db()->type('select_count') : null );
-    if (empty($select_count)) $select_count = array('','');
+    if (stripos($this->name,' ') !== false) {
+      $sql = $this->name;
+      $limit = $where = '';
 
-    $sql = "SELECT ".trim("$select_count[0] *"). $this->select_extras();
-    $sql .= " FROM ".$this->sql_name();
-    $sql .= $where;
+    } else {
 
-    if ($this->p('orderby')) $sql .= ' ORDER BY '.$this->p('orderby');
+      $where = $this->where_criterias($this->p(),$this->p('op'));
+      $select_count = ( $where ? $this->db()->type('select_count') : null );
+      if (empty($select_count)) $select_count = array('','');
 
-    if ($this->p('limit')) {
-      $limit = $this->p('limit');
-      $sql .= ' LIMIT '.$limit;
-    } else {
-      $limit = '';
+      $sql = "SELECT ".trim("$select_count[0] *"). $this->select_extras();
+      $sql .= " FROM ".$this->sql_name();
+      $sql .= $where;
+
+      if ($this->p('orderby')) $sql .= ' ORDER BY '.$this->p('orderby');
+
+      if ($this->p('limit')) {
+        $limit = $this->p('limit');
+        $sql .= ' LIMIT '.$limit;
+      } else {
+        $limit = '';
+      }
     }
 
     //
@@ -572,6 +578,14 @@ Class Table extends nb {
     $st = $this->db()->conn->prepare($sql);
     $st->execute();
 
+    # Fields
+    $fields = array();
+    foreach ($this->db()->fields($st) as $f) { $fields[$f->name] = $f; }
+    $this->fields = $fields;
+    #debug($fields);
+    #bye($this->name);
+    if (!$this->p('action')) echo $this->html_menu();
+
     if (!isset($opt['is_html'])) $opt['is_html'] = preg_match('/^(table|div)$/',$format)
       ? (
         $this->p('header')!=="0"
@@ -606,10 +620,10 @@ Class Table extends nb {
         if ($opt['is_html']) echo $this->html_rows_top();
 
         if ($out_conf) {
-          out::head($out_conf,$this->fields(),array($row));
+          out::head($out_conf,$fields,array($row));
 
         } else {
-          echo $this->{"rows_begin_$format"}($this->fields());
+          echo $this->{"rows_begin_$format"}($fields);
         }
 
       }
@@ -621,7 +635,7 @@ Class Table extends nb {
 
       $count_fields = 0;
 
-      foreach ($this->fields() as $f => $field) {
+      foreach ($fields as $f => $field) {
         $row[$f] = $field->out($row[$f]);
         $count_fields++;
       }
@@ -629,7 +643,7 @@ Class Table extends nb {
       if ($out_conf) {
         out::row($out_conf,$row);
       } else {
-        echo $this->{"rows_rec_$format"}($row);
+        echo $this->{"rows_rec_$format"}($row,$fields);
       }
 
     }
@@ -675,7 +689,7 @@ Class Table extends nb {
       }
 
       if ($count === 0 and $this->p('header') === 'force') {
-        echo $this->{"rows_begin_$format"}($this->fields());
+        echo $this->{"rows_begin_$format"}($fields);
       }
 
       if ($count) {
@@ -710,12 +724,12 @@ Class Table extends nb {
     return "\n-- ".$this->name."\n";
   }
 
-  public function rows_rec_sql(&$row) {
+  public function rows_rec_sql(&$row,$fields) {
     $keys = $values = array();
 
     foreach ($row as $k=>$v) {
       if (isset($this->extras[$k])) continue;
-      $f = $this->fields($k);
+      $f = $fields[$k];
 
       $values[] = $f->quote($v);
       $keys[] = $f->sql_name();
@@ -1036,7 +1050,7 @@ Class Table extends nb {
     }
 
     #debug($execute);
-    $info = array('sql'=>$sql,'values'=>$hvalues,'return'=>$query->rowCount());
+    $info = array('sql'=>$sql,'values'=>$hvalues,'rowCount'=>$query->rowCount());
     $this->debug($info,1);
     return $query->rowCount();
 
@@ -1054,7 +1068,7 @@ Class Table extends nb {
 
     $sql = 'DELETE FROM ' . $this->sql_name() . $where;
     #bye($sql);
-    return $this->db()->exec($sql);
+    return $this->db()->exec($sql)->fetchColumn();
   }
 
 # NB 01.04.16   public function out($v,$head=false) { return $this->db()->out($v,$head); }
diff --git a/lib/php/db/types.php b/lib/php/db/types.php
deleted file mode 100644 (file)
index 6edb27e..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-<?php
-require_once(dirname(__FILE__).'/../nb.php');
-$DB_TYPES = array(
-
-  'use_path' => array(
-    'sqlite' => true,
-  ),
-
-  'sqliteCreateFunction' => array(
-    'sqlite' => array(
-      'ip2int' => function ($value) { return ip2long($value); },
-      'concat' => function ($v1,$v2) { return $v1.$v2; },
-      'regexp' => function ($pattern, $data, $delimiter = '~', $modifiers = 'isuS') {
-          if (isset($pattern, $data) === true) {
-            return (preg_match(sprintf('%1$s%2$s%1$s%3$s', $delimiter, $pattern, $modifiers), $data) > 0);
-          }
-          return null;
-        }
-      ,
-      'to_char' => array(function ($value,$format) {
-          $replace = array(
-              'YYYY' => '%Y',
-              'MM' => '%m',
-              'WW' => '%W',
-              'DD' => '%d',
-          );
-          $format = str_replace(array_keys($replace),array_values($replace),$format);
-          return strftime($format,strtotime($value));
-        }
-      ,2),
-    ),
-  ),
-
-  'localFile' => array(
-    # hostname:port:database:username:password
-    'sqlite' => array(getenv('HOME').'/'.'.sqlite', '^(?:user(?:name)?=(?P<user>\S+)|password=(?P<password>\S+))'),
-    'mysql' => array(getenv('HOME').'/'.'.my.cnf', '^(?:user(?:name)?=(?P<user>\S+)|password=(?P<password>\S+))'),
-    'pgsql' => array(getenv('HOME').'/'.'.pgpass', '^[^:]+:[^:]+:<NAME>:(?P<user>[^:]+):(?<password>[^:]+)'),
-    #'sqlite' => array($_SERVER['HOME'].'/'.'.db.pass', '^<NAME>:(?P<user>[^:]*):(?<password>[^:]*)'),
-    #'sqlite' => array(),
-  ),
-
-  'tables' => array(
-    'sqlite' => "SELECT name,type FROM sqlite_master WHERE type IN('table','view') AND name NOT LIKE 'sqlite_%' ORDER BY name",
-    'mysql' => "SELECT TABLE_NAME as name"
-      .",LOWER(IF(TABLE_TYPE='BASE TABLE','TABLE',TABLE_TYPE)) as type"
-      .",ENGINE as engine"
-      .",CREATE_TIME as created"
-      ." FROM information_schema.tables WHERE TABLE_SCHEMA=DATABASE()"
-    ,
-    'pgsql' => "SELECT table_name as name"
-      .",LOWER(CASE table_type WHEN 'BASE TABLE' THEN 'TABLE' ELSE table_type END) as type"
-      .",table_type"
-      ." FROM information_schema.tables WHERE table_type in('BASE TABLE','VIEW') AND table_schema NOT IN ('pg_catalog', 'information_schema')"
-    ,
-  ),
-
-  'table.fields' => array(
-    'sqlite' => array(
-      'sql' => "PRAGMA table_info('<NAME>')",
-      'fct' => create_function('&$r',join('',array(
-        #'debug("zaza");',
-        '$r["key"] = $r["pk"] == "0" ? 0 : 1;',
-        '$r["default"] = $r["dflt_value"];',
-        '$r["null"] = $r["notnull"] == "0" ? 1 : 0;',
-        '$r["autoincrement"] = preg_match("/[\(,]".$r["name"]." [^\),]+ AUTOINCREMENT/",$r["this"]->sql()) ? 1 : 0;',
-      ))),
-    ),
-    'mysql' => array(
-      'sql' => "SHOW COLUMNS FROM `<NAME>`",
-      'fct' => create_function('&$r',join('',array(
-        '$r["autoincrement"] = $r["extra"] == "auto_increment" ? 1 : 0;',
-        '$r["name"] = $r["field"];',
-      ))),
-    ),
-    'pgsql' => array(
-      'fct' => create_function('&$r',join('',array(
-        'if (!isset($r["pg_default"])) return;',
-        'if (preg_match("/^nextval\(/",$r["pg_default"])) { $r["autoincrement"] = 1; }',
-        'elseif (preg_match("/^\'\'/",$r["pg_default"])) { $r["default"] = ""; }',
-        'else { $r["default"] = $r["pg_default"]; }',
-      ))),
-      'sql' => "SELECT
-a.attname AS name,
-pg_catalog.format_type(a.atttypid, a.atttypmod) AS type,
-CASE a.attnotnull WHEN 'f' then 1 ELSE 0 END AS null,
-(SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128) FROM pg_catalog.pg_attrdef d WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) AS pg_default,
-(SELECT 1 FROM pg_index i WHERE a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) AND i.indrelid = '<NAME>'::regclass AND i.indisprimary) as key
-FROM pg_catalog.pg_attribute a
-WHERE a.attrelid = (
-  SELECT c.oid FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relname='<NAME>' AND pg_catalog.pg_table_is_visible(c.oid)
-  )
-  AND a.attnum > 0 AND NOT a.attisdropped
-ORDER BY a.attnum",
-    ),
-  ),
-
-  'table.sql' => array(
-    'sqlite' => "SELECT sql FROM sqlite_master WHERE name='<NAME>'",
-    'mysql' => "SHOW CREATE TABLE `<NAME>`",
-    # c.relkind::char
-    'pgsql' => "
-SELECT CASE c.relkind::char WHEN 'r' THEN (
-SELECT
-  'CREATE TABLE '||sql.table||'(".NB_EOL." '
-    ||array_to_string(array_agg(sql),',".NB_EOL." ')
-  ||'".NB_EOL.")' as sql
-FROM (
-  (
-    SELECT -- FIELDS
-      c.oid AS id
-      ,c.relname as table
-      ,9 as prio
-      ,''
-        || f.attname
-        || ' ' || pg_catalog.format_type(f.atttypid,f.atttypmod)
-        ||CASE WHEN f.attnotnull THEN ' NOT NULL' ELSE '' END
-        ||CASE WHEN f.atthasdef = 't' AND d.adsrc !=''THEN ' DEFAULT '||d.adsrc ELSE '' END
-      AS sql
-    FROM pg_attribute f
-        JOIN pg_class c ON c.oid = f.attrelid
-        LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum
-    WHERE c.relkind::char IN ( 'r' ) --, 'v' )
-    AND f.attnum > 0
-    ORDER BY f.attnum
-  )  UNION (
-    SELECT -- CONSTRAINTS
-        c.oid as id
-        ,c.relname as table
-        ,0 as prio
-        ,CASE
-          WHEN p.contype = 'p' THEN 'PRIMARY KEY'
-          WHEN p.contype = 'u' THEN 'UNIQ'
-          ELSE '' END
-        ||'('||array_to_string(array_agg(f.attname),', ')||')' AS sql
-    FROM pg_attribute f
-        JOIN pg_class c ON c.oid = f.attrelid
-        LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey)
-    WHERE c.relkind = 'r'::char
-        AND f.attnum > 0
-        AND p.contype IN ('u','p')
-    GROUP BY c.oid,p.contype,f.attrelid,c.relname
-    ORDER BY c.oid,f.attrelid
-  )
-ORDER BY prio DESC) sql
-WHERE sql.table='<NAME>'
-GROUP BY sql.id,sql.table
-)
-WHEN 'v' THEN trim(regexp_replace(pg_catalog.pg_get_viewdef(c.oid::pg_catalog.oid, true),'\s\s+',' ','g'))
-ELSE 'NOT' END as sql
-FROM pg_catalog.pg_class c WHERE c.relname = '<NAME>' AND pg_catalog.pg_table_is_visible(c.oid)
-        ", # < table.sql:psql "SELECT
-  ),
-);
-#die($DB_TYPES['tables']['mysql']);
-return;
-if (empty($argv) or count($argv)<2) return;
-$new = array();
-$filter = $argv[1];
-foreach ($DB_TYPES as $key => $types) {
-  foreach ($types as $type => $val) {
-    if($filter and $filter!=$type) continue;
-    $new[$type][$key] = $val;
-  }
-}
-var_export($new);
-?>
index 00ac3474cc11798d78c70cfce0e5477cfc451e4c..227e98f6e1adbbbf04cb638378148f9fa8b66c3f 100644 (file)
@@ -130,7 +130,8 @@ function err($msg='__err__',$preff='err',$backtrace_deep=0) {
 
 function debug($msg,$level=0) {
   if ($level and $level>nb::p('debug')) return;
-  $msg = is_scalar($msg) ? $msg : print_r($msg,true);
+  #$msg = is_scalar($msg) ? $msg : print_r($msg,true);
+  $msg = is_scalar($msg) ? $msg : var_export($msg,true);
 
   if (nb::client_header('Accept','ml')) {
     $msg = '<pre class="debug">'