]> git.nbdom.net Git - nb.git/commitdiff
Bed
authorNicolas Boisselier <nicolas.boisselier@gmail.com>
Sun, 17 Apr 2016 23:07:24 +0000 (00:07 +0100)
committerNicolas Boisselier <nicolas.boisselier@gmail.com>
Sun, 17 Apr 2016 23:07:24 +0000 (00:07 +0100)
etc/profile.d/mac.sh
lib/php/db.php
lib/php/db/field.php
lib/php/db/table.php
lib/php/db/types/mysql.php
lib/php/db/types/sqlite.php
lib/php/nb.php
lib/php/out.php

index d077a7755298a5ada0012da93e131d174f7356e5..36828f10411514ed8a8a6dae10cb8d65fd7dc1a7 100644 (file)
@@ -5,7 +5,7 @@ mac_pbcopy() {
 [ -z "$DARWIN" ] && return 0
 
 [ -x /opt/local/bin/mysqld_safe5 ] && alias mac_mysqlstart='sudo /opt/local/bin/mysqld_safe5 &'
-[ -x /opt/local/bin/mysqladmin5 ] && alias mac_mysqlstop='sudo /opt/local/bin/mysqladmin5 -p shutdown'
+[ -x /opt/local/bin/mysqladmin5 ] && alias mac_mysqlstop='sudo /opt/local/bin/mysqladmin5 -u root -p shutdown'
 [ -x /Applications/iTunes.app/Contents/MacOS/iTunes ] && alias iTunes=/Applications/iTunes.app/Contents/MacOS/iTunes
 [ -x /Applications/VLC.app/Contents/MacOS/VLC ] && alias vlc=/Applications/VLC.app/Contents/MacOS/VLC
 
index 55ebbcf3b02a6b2bf6e55179bf9c4c94857f09ab..47affa05f5b3d5795c399695aeb11609c26f6a65 100644 (file)
@@ -15,6 +15,7 @@ $DB_TYPES = array(); # See db/types/*.php
 class Db extends nb {
 
   # PDO Connection
+  public static $encoding = 'utf-8';
   public $conn;
   public $pdo;
 # NB 07.04.16   public $pdo_error = array( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); # See: http://php.net/manual/en/pdo.error-handling.php
@@ -157,7 +158,7 @@ class Db extends nb {
     if (empty($this->conn)) return false;
 
     # Type queries
-    if ($sql = $this->type('post_connect')) {
+    if ($sql = $this->type('exec')) {
       if (is_scalar($sql)) $sql = array($sql);
       foreach ($sql as $s) {
         $this->conn->exec($s);
@@ -267,6 +268,8 @@ class Db extends nb {
   }
 
   function quote($v) {
+    static $fct = false; if ($fct === false) $fct = $this->type('quote');
+    if ($fct) return $fct($v);
     return $this->conn->quote($v);
   }
 
@@ -302,25 +305,26 @@ class Db extends nb {
     return $return;
   }
 
-  public function type($key=null,$die=false) {
+  public function type($key=null,$die=false,$type=null) {
     global $DB_TYPES;
+    if (!$type) $type = $this->type;
 
     static $require = array();
-    if (empty($require[$this->type])) {
-      #if (empty($this->type)) return;
-      if (empty($this->type)) self::bye("Type is required");
-      require_once(dirname(__FILE__).'/db/types/'.$this->type.'.php');
-      $require[$this->type] = 1;
+    if (empty($require[$type])) {
+      #if (empty($type)) return;
+      if (empty($type)) self::bye("Type is required");
+      require_once(dirname(__FILE__).'/db/types/'.$type.'.php');
+      $require[$type] = 1;
     }
 
-    if ($key === null) return $DB_TYPES[$this->type];
+    if ($key === null) return $DB_TYPES[$type];
 
-    if (empty($DB_TYPES[$this->type][$key])) {
-      if ($die) self::bye("db.type(): Unknow key `$key` for type `".$this->type."`");#.' - '.print_r($DB_TYPES,true));
+    if (empty($DB_TYPES[$type][$key])) {
+      if ($die) self::bye("db.type(): Unknow key `$key` for type `".$type."`");#.' - '.print_r($DB_TYPES,true));
       return;
     }
 
-    return $DB_TYPES[$this->type][$key];
+    return $DB_TYPES[$type][$key];
   }
 
   public function tables() {
@@ -563,11 +567,11 @@ EOF;
   }
 
   public function dump() {
-    $this->sql(true);
+    return $this->sql(true);
   }
 
   public function pdo_info() {
-    return preg_replace_callback('/(\w+)=[^;]*;?/',function($m){
+    return preg_replace_callback('/(\w+)=([^;]*)(;?)/',function($m){
       return preg_match('/^(host|dbname|name)/',$m[1]) ? $m[0] : ''; 
     },$this->pdo);
   }
@@ -576,14 +580,24 @@ EOF;
     if ($insert === null) $insert = self::p('insert');
     $this->pset('orderby',null);
     $this->pset('format','sql');
-    $r = array();
 
-    $tables = array();
-    foreach (explode(',',self::p('table')) as $t) {
-      $tables[$t] = 1;
+    # Tables param filter
+    $tables = $this->tables();
+    if (self::p('table')) {
+      $new = array();
+      foreach (explode(',',self::p('table')) as $t) {
+        $new[$t] = $tables[$t];
+      }
+      $tables = $new;
     }
     #if (NB_EOL == "\n")
 
+    # Change db type
+    foreach ($tables as $t) { $t->fields(); }
+    if (self::p('db.type')) {
+      $this->type = self::p('db.type');
+    }
+
     echo ''
       #."-- Database : ".$this->name."\n"
       ."-- Date     : ".strftime('%F %T')."\n"
@@ -591,27 +605,25 @@ EOF;
       #."-- Host     : ".$this->host."\n"
     ;
 
-# NB 03.04.16     if ($insert) {
-# NB 03.04.16       if ($sql = $this->type('post_connect')) {
-# NB 03.04.16         if (is_scalar($sql)) $sql = array($sql);
-# NB 03.04.16         foreach ($sql as $s) {
-# NB 03.04.16           echo "$sql;\n";
-# NB 03.04.16         }
-# NB 03.04.16       }
-# NB 03.04.16     }
-
-    foreach ($this->tables() as $t) {
-      if ($tables and empty($tables[$t->name])) continue;
+    if ($sql = $this->type('exec')) {
+      foreach ((is_array($sql) ? $sql : array($sql)) as $sql) {
+        echo rtrim($sql,';').";\n";
+      }
+    }
+
+    foreach ($tables as $t) {
+      if (!empty($tables) and empty($tables[$t->name])) continue;
       if ($insert) {
         echo "\n-- Table: ".$t->name."\n";
-        #echo 'DROP TABLE IF EXISTS '.$t->sql_name().';'.NB_EOL;
-        echo 'DROP '.strtoupper($t->type).' IF EXISTS '.$t->sql_name().';'.NB_EOL;
       }
-      echo rtrim($t->sql(),';').';'.NB_EOL;
+      #echo 'DROP TABLE IF EXISTS '.$t->sql_name().';'.NB_EOL;
+      echo 'DROP '.strtoupper($t->type).' IF EXISTS '.$t->sql_name().';'.NB_EOL;
+      echo rtrim($t->create(),';').';'.NB_EOL;
       if ($insert and $t->type == 'table') $t->rows();
       #break;
     }
-    return $r;
+
+    return true;
   }
 
   public function status() {
index ccb7198ef4900ea7feadfa3a3d60b9020b3e1926..b422f938f1785f0c04ffa95ebe0c51d7b7e5b805 100644 (file)
@@ -11,11 +11,10 @@ $DB_FIELD_TYPES = array(
 class field {
   private $table;
   public $name;
-  #public $type = 'text';
   public $type;
   public $null = true;
-  public $key = false;
-  #public $value;
+  public $key = 0;
+  public $uniq = 0;
   public $default;
   public $autoincrement;
   public $extra;
@@ -25,6 +24,7 @@ class field {
     'type',
     'null',
     'key',
+    'uniq',
     'default',
     'autoincrement',
     'extra',
@@ -43,6 +43,10 @@ class field {
     return preg_match('/signed|(snall )?int|float|decimal|numeric|number|currency/i',$this->type) ? true : false;
   }
 
+  public function unsigned() {
+    return ( stripos($this->type,'unsigned') !== false ? true : false );
+  }
+
   public function html_type() {
     # See: http://www.w3schools.com/html/html_form_input_types.asp
     if (strpos($this->name,'password') !== false) return 'password';
@@ -84,6 +88,15 @@ class field {
   }
 
   public function size() {
+
+    # Enum type
+    if (preg_match("/enum\('(.*?)'\)/i",$this->type,$m)) {
+      $m = explode("\t",preg_replace("/' *, *'/","\t",$m[1]));
+      $m = array_map(function($v){return strlen($v);},$m);
+      rsort($m,SORT_NUMERIC);
+      return $m[0];
+    }
+
     if (! preg_match('/\((\d+)(?:,(\d+)\))?/',$this->type,$m) ) return null;
     array_shift($m);
 #debug($m);
@@ -143,7 +156,7 @@ class field {
     if ($value === null) return 'NULL';
     if ($force_quote or !$this->numeric()) {
 
-      if (($db = $this->db()) === null) return "'".preg_replace("/'/","\\'",$value)."'";
+      if (!($db = $this->db())) return "'".preg_replace("/'/","\\'",$value)."'";
       return $db->quote($value);
 
     } else {
index dd65fe5eab1de7c261cd7788871635f4871c5f46..4b01c8dd4a8d9d402d70ab0b249a7a6b51468320 100644 (file)
@@ -107,6 +107,46 @@ Class Table extends nb {
     return $db;
   }
 
+  /*
+   * Function create
+   *
+   * return the sql to create the table build internaly
+   *
+   */
+  public function create() {
+
+    // Type specific
+    global $_create_fct, $_create_fct_type;
+    $_create_fct_type = $this->db()->type('create',false,self::p('db.type'));
+
+    $_create_fct = function(&$field) {
+      global $_create_fct_type; if ($_create_fct_type and ($sql=$_create_fct_type($field))) return $sql;
+
+      return $field->sql_name().' '.$field->type
+        .($field->null ? ' NULL' : ' NOT NULL')
+        .($field->default !== null ? ' DEFAULT '.$field->quote($field->default,true) : '')
+        .($field->key ? ' PRIMARY KEY' : '')
+        .($field->uniq ? ' UNIQUE' : '')
+      ;
+    };
+
+    $sql = 'CREATE TABLE '.$this->sql_name()
+      .' ('
+      .join(",",array_map(function($f){global $_create_fct;return $_create_fct($f);},array_values($this->fields())))
+      # done at the end for primary keys .')'
+    ;
+
+    // Handle multiple primary keys syntaxe
+    if (substr_count(strtoupper($sql),'PRIMARY KEY')>1) {
+      $sql = str_ireplace(' PRIMARY KEY','',$sql)
+        .', PRIMARY KEY ('.join(',',array_map(function($f){return $f->sql_name();},$this->fields_keys())).')'
+      ;
+    }
+
+    unset($_create_fct,$_create_fct_type);
+    return $sql.')';
+  }
+
   /*
    * Function sql
    *
@@ -178,18 +218,20 @@ Class Table extends nb {
         $field = array(
           'name'          => $row['name'],
           'type'          => strtolower($row['type']),
-          'default'       => (isset($row['default']) ? $row['default'] : null),
           'key'           => (preg_match('/^(f.*|no|0)?\s*$/i',$row['key']) ? 0 : 1),
           'null'          => (preg_match('/^(f.*|no|0)?\s*$/i',$row['null']) ? 0 : 1),
           'extra'         => null, # !!! nothing todo with array $extra, this info from the sql server
           'autoincrement' => (isset($row['autoincrement']) ? $row['autoincrement'] : 0),
         );
+        if (isset($row['uniq'])) $field['uniq'] = $row['uniq'];
+        if (isset($row['default'])) $field['default'] = $row['default'];
 
         $this->fields[$field['name']] = new Field($field);
+        $this->fields[$field['name']]->size = $this->fields[$field['name']]->size();
 
       }
 
-      if (empty($this->fields)) bye("Table `".$this->name."` does not exists into database ".$this->db()->name."!");
+      if (empty($this->fields)) bye("Table `".$this->name."` does not exists");
 
     } # < $this->fields
 
@@ -647,6 +689,16 @@ Class Table extends nb {
         foreach ($row as $k=>$v) {
           if (!isset($this->extras[$k])) $row[$k] = out::format($v);
         }
+
+      /*
+      */
+      } elseif(0) {
+        //iconv(mb_detect_encoding($text, mb_detect_order(), true), "UTF-8", $text);
+        foreach ($row as $k=>$v) {
+          #if (!isset($this->extras[$k])) $row[$k] = mb_convert_encoding($v, "UTF-8");
+          #if (!isset($this->extras[$k])) $row[$k] = preg_replace('/[\r\f]/','',$v);
+        }
+
       }
 
       if ($extras and !empty($this->row_parse_post)) {
index c01662f53119a7f1255a9d1bea334212e073eb43..cb9ebd78c5c35fc884b7a6039ad001f619f246bd 100644 (file)
@@ -3,7 +3,7 @@ $DB_TYPES['mysql'] = array (
 
 'quote_name' => '`',
 #'select_count' => array('SQL_CALC_FOUND_ROWS','SELECT FOUND_ROWS()'),
-'post_connect' => 'SET NAMES utf8',
+'exec' => 'SET NAMES '.str_replace('utf-8','utf8',strtolower(Db::$encoding)),
 'extra_where' => 'having',
 
 'localFile' => array (getenv('HOME').'/.my.cnf','^(?:user(?:name)?=(?P<user>\\S+)|password=(?P<password>\\S+))'),
@@ -65,6 +65,9 @@ $DB_TYPES['mysql'] = array (
   'fct' => create_function('&$r',join('',array(
     '$r["autoincrement"] = $r["extra"] == "auto_increment" ? 1 : 0;',
     '$r["name"] = $r["field"];',
+    #'debug($r["key"]);',
+    '$r["uniq"] = $r["key"] == "UNI" ? 1 : 0;',
+    '$r["key"] = $r["key"] == "PRI" ? 1 : 0;',
   ))),
 ),
 
index e0d9c276c2b51a62561d8b4d1c06c8eadc88c03d..476138cb3e1cf0a478632e136f28f741c8c4f75d 100644 (file)
@@ -1,9 +1,11 @@
 <?php
 $DB_TYPES['sqlite'] = array (
+'exec' => 'PRAGMA encoding = "'.strtoupper(Db::$encoding).'"', 
 'use_path' => true,
 'extra_where' => 'denorm',
 
 'quote_name' => '`',
+'quote' => function(&$v) { return "'".str_replace("'","''",$v)."'"; },
 
 'table.sql' => 'SELECT sql FROM sqlite_master WHERE name=\'<NAME>\'',
 
@@ -43,4 +45,14 @@ $DB_TYPES['sqlite'] = array (
   ))),
 ),
 
+'create' => function(&$field) {
+  if ($field->autoincrement) return $field->sql_name().' INTEGER PRIMARY KEY AUTOINCREMENT';
+  $field->size = $field->size();
+  $r = array(
+    '/^(.*?) (unsigned)( .*?)?$/i' => '\2 \1\3',
+    '/enum\(.*?\)/i' => 'VARCHAR'.($field->size ? "($field->size)" : '')
+  );
+  $field->type = preg_replace(array_keys($r),array_values($r),$field->type);
+},
+
 );?>
index fcaf7f930dc6d6003f7e608da1b12b8fcf95b831..917204617c85e4480a3fe2fe3c956d9d75bda910 100644 (file)
@@ -492,6 +492,7 @@ class NB {
     else self::bye("Unknow action: `$action`");
     #else $rows = $class->$name;
     if (!$rows) return false;
+    if ($rows === true) return true;
 
     #bye($rows);
     if (is_scalar($rows)) {
index 451cdfe9c1db97659fed71c61821935786cdeacd..ad31cef8bbf50df74d096d6b89e656c354077df5 100644 (file)
@@ -375,7 +375,7 @@ function out_csv(&$row,$o) {
   }
 
   #echo join($o['sep'],array_values($row));
-  echo str_replace("\n",'|',join($o['sep'],$values));
+  echo str_replace("\n",'\\n',join($o['sep'],$values));
 }
 
 function out_csv_head(&$row,$o) {