my %CMD_ALIASE = (
# NB 09.04.16 'd' => 'db',
# NB 09.04.16 't' => 'table',
-# NB 09.04.16 'f' => 'format',
+ 'f' => 'format',
# NB 09.04.16 'l' => 'limit',
# NB 09.04.16 'a' => 'action',
# NB 09.04.16 'h' => 'header',
}
sub csv2txt {
+ # sprintf missing argument warning message ????
+ # Can't open XXX: No such file or directory
+ no warnings;
+
my $sep = shift;
my $noheader = shift;
my @lines = ();
my $l;
- # sprintf missing argument warning message ????
- # Can't open XXX: No such file or directory
- no warnings;
-
#open(STDOUT,">&2");
#
# Store lines and lengths in memory
csv2txt_next:
my @len = ();
+ #warn @{$lines[0]};
+ my $count=0;
for (@lines) {
my @F = @$_;
+ last if $count and @F and $F[0] =~/^\r/;
+ $count++;
+
for (my $i=0;$i<@F;$i++) {
$len[$i] = length($F[$i]) unless defined $len[$i];
$len[$i] = $l if ( $l = length($F[$i]) ) >= $len[$i];
if ($_->[0] =~ s/^\r// and $i) {
csv_end();
print "\n";
- push @lines,$_;
+ unshift @lines,$_;
goto csv2txt_next;
}
printf $format,@$_;
$CONF = array (
'nb' => array (
'host' => 'admin.izideal.vpn',
- 'user' => 'nico',
- 'password' => 'mpc60ax73',
'type' => 'mysql',
'name' => 'nb',
+ 'user' => 'nico',
+ '_import' => '_nico',
'default_table' => 'rent',
'tables' => array(
'rent' => array(
- 'order_by' => 'start desc',
+ 'orderby' => 'start desc, end desc',
'replace' => array (
'idtenant' => 'tenant.name',
'idplace' => 'addr.addr',
),
- 'call_rows' => function(&$r) {
- if (0) $r['rent_year'] = $r['rent'] * (1 +
- ( date('m',$r['end'])+12*date('Y',strtotime($r['end'])) )
- -
- ( date('m',$r['start'])+12*date('Y',strtotime($r['start'])) )
- );
+ 'row_parse_pre' => function(&$r) {
#extra: "rent * (1 + ( strftime('%m',end)+12*strftime('%Y',end) ) - ( strftime('%m',start)+12*strftime('%Y',start) ))"
#$r['rent_year'] = $r['rent'] * (1 + ( date('m',strtotime($r['end']))+12
$r['Total'] = $r['rent'] + $r['charge'];
- }
+ if (1) $r['rent_year'] = sprintf('%.2f',$r['rent'] * (1 +
+ ( date('m',strtotime($r['end'])) + 12 * date('Y',strtotime($r['end'])) )
+ -
+ ( date('m',strtotime($r['start'])) + 12 * date('Y',strtotime($r['start'])) )
+ ));
+ },
+ 'row_parse_post' => function(&$r) {
+ $r['revision'] = join(' ',array(
+ '<a href="template/?id=quittance.html&idplace='.$r['idplace'].'&idtenant='.$r['idtenant'].'&start=2015-04-01">quittance</a>',
+ '<a href="template/?id=revision.txt&idplace='.$r['idplace'].'&idtenant='.$r['idtenant'].'&start=2015-04-01">revision</a>',
+ ));
+ },
),
),
),
+_nico:
+ user: nico
+
_mysql:
type: mysql
_import:
- _nico
- _mysql
-nb:
+___nb:
host: admin.izideal.vpn
_import:
- _nico
test:
type: "int"
extra: 1
-izi:
- #pdo: 'mysql:host=admin.izideal.com;port=3306;dbname=izi'
- title: Mysql Izi on Admin
- default_table: process
- host: admin.izideal.vpn
- user: izideal
- name: izi
- _import:
- - _nico
- - _mysql
- tables:
- site:
- replace:
- idlang: lang.id
-
-izidev:
- host: big.cascais.loc
- title: Mysql Izi on Big
- #user: nico
- _import:
- - izi
- - _nico
ui:
pdo: 'sqlite:/opt/semantico/product/releases/sem_ui/db/semantico.db'
default_table: node
tables:
node:
- order_by: "(SELECT value FROM fact WHERE idnode=id AND name='date_install') DESC"
+ orderby: "(SELECT value FROM fact WHERE idnode=id AND name='date_install') DESC"
replace_:
iddc: dc.id
replace:
id: addr.addr
rent:
- order_by: "start desc"
+ orderby: "start desc, end desc"
replace:
idtenant: tenant.name
idplace: addr.addr
#extra: "rent * (1 + ( date_format(end,'%m')+12*date_format(end,'%Y') ) - ( date_format(start,'%m')+12*date_format(start,'%Y') ))"
#revision: (SELECT GROUP_CONCAT('<a href="template/?id='||id||'&idplace='||idplace||'&idtenant='||idtenant||'&start='||start||'">'||substr(id,0,instr(id,'.'))||'</a>',' ') FROM template)
-# TODEL - NB 10.01.16
-# NB 10.01.16 sort:
-# NB 10.01.16 rent: start desc
-# NB 10.01.16 extras:
-# NB 10.01.16 rent:
-# NB 10.01.16 total:
-# NB 10.01.16 type: "float(8,2)"
-# NB 10.01.16 extra: "ROUND(rent+charge,2)"
-# NB 10.01.16 rent_year:
-# NB 10.01.16 type: "float(8,2)"
-# NB 10.01.16 extra: "rent * (1 + ( strftime('%m',end)+12*strftime('%Y',end) ) - ( strftime('%m',start)+12*strftime('%Y',start) ))"
-# NB 10.01.16 #revision: (SELECT GROUP_CONCAT('<a href="template/?id='||id||'&idplace='||idplace||'&idtenant='||idtenant||'&start='||start||'">'||substr(id,0,instr(id,'.'))||'</a>',' ') FROM template)
-# NB 10.01.16 template:
-# NB 10.01.16 View: "'<a href=\"/template/'||id||'\">'||id||'</a>'"
+izi:
+ #pdo: 'mysql:host=admin.izideal.com;port=3306;dbname=izi'
+ title: Mysql Izi
+ host: sql.izideal.vpn
+ default_table: process
+ user: izideal
+ name: izi
+ _import:
+ - _mysql
+ tables:
+ site:
+ replace:
+ idlang: lang.id
+
+admin:
+ title: Mysql Izi on Admin
+ host: admin.izideal.vpn
+ _import:
+ - izi
+
+izidev:
+ host: big.cascais.loc
+ title: Mysql Izi on Big
+ #user: nico
+ _import:
+ - izi
+ - _nico
+
+media:
+ host: media.izideal.vpn
+ name: mysql
+ _import:
+ - _mysql
+ - _nico
+
postfix:
#pdo: 'mysql:host=media.izideal.vpn;port=3306;dbname=postfix'
title: Postfix on Izideal
that.table2div('table.rows');
return true;
} else {
- $('table.rows').addClass('t2d');
+ $('.block table, table.block, table.rows').addClass('t2d');
$('.t2d-th').each(function(){ $(this).remove(); });
}
#preg_match_all('/[:;](user|username|password)=([^;]*)/',$this->pdo,$m); bye($m);
if( !$this->type ) return false;
if ($this->type('use_path')) {
- $this->name = preg_replace('/^\w+:/','',$this->pdo);
+ $this->file = preg_replace('/^\w+:/','',$this->pdo);
+ $this->host = $this->file;
} else {
}
#$this->bye($this->pdo);
+ if ($p = $this->p('db.host')) $this->host = $p;
+
# Add args to pdo
foreach (array(
'host' => 'host',
if (!$this->type(null)) $this->bye("Unknow type = `".$this->type."`");
# Connect
- if ($this->type('use_path') and !is_readable($this->name)) {
- $this->bye("Can't read database file `".$this->name."` type=`$this->type`",false);
-
+ if ($this->type('use_path') and !is_readable($this->file)) {
+ $this->bye("Can't read database file `".$this->file."` type=`$this->type`",false);
}
+
try {
$this->conn = new PDO($this->pdo,$this->user,$this->password,$this->options);
#$this->conn = new PDO($this->pdo,$this->user,$this->password,$this->pdo_error);
Table
*/
if (empty($Db)) return false;
+ if (self::p('action') and
+ !self::p('table') and
+ !preg_match('/^(table\.\w+|rows|insert|edit|delete|update)$/',self::p('action'))
+ ) return true;
if (!$Db->p('table') and isset($Db->default_table)) $Db->pset('table',$Db->default_table);
if (!$Db->p('table') and ($v = array_keys($Db->tables()))) $Db->pset('table',$Db->ar_first($v));
public function status() {
- if (!($status=$this->type('status'))) return array();
-
- $new = array();
- foreach ($status as $sql => $fct) {
-
- try {
- $sth = $this->conn->prepare($sql);
- $sth->execute();
- } catch(PDOException $e){
- continue;
- }
-
- $rows = $sth->fetchAll(PDO::FETCH_BOTH);
- foreach ($rows as $i=>$r) {
- if ($v = $fct($r)) $new += $v;
- }
- #$status = $new;
- #debug($rows);
- }
+ $status = $new = array();
$new = array(
'host' => $this->host,
'tables' => count($this->tables()),
)+$new;
- $status = array();
+ if (($sqls=$this->type('status'))) {
+
+ foreach ($sqls as $sql => $fct) {
+
+ try {
+ $sth = $this->conn->prepare($sql);
+ $sth->execute();
+ } catch(PDOException $e){
+ continue;
+ }
+
+ $rows = $sth->fetchAll(PDO::FETCH_BOTH);
+ foreach ($rows as $i=>$r) {
+ if ($v = $fct($r)) $new += $v;
+ }
+ #$sqls = $new;
+ #debug($rows);
+ }
+
+ } # << type.status
+
#debug($new);
foreach ($new as $k=>$v) {
$status[] = array(
}
return $status;
- /*
- */
-
- return array(
- 'host' => $this->host,
- 'port' => $this->port,
- 'name' => $this->name,
- 'user' => $this->user,
- #'tables' => count($this->tables()),
- #'dbs' => count($this->dbs),
- 'tables' => count($this->tables()),
- #'tables' => join(' ',array_keys($this->tables())),
- #'dbs' => join(' ',array_values($this->dbs)),
- )+$status;
-
}
public function fields($st) {
#if (!defined('DB_HTML_BUTTON_ADD')) define('DB_HTML_BUTTON_ADD','<input type="submit" class="button" value="Add" onclick="this.setAttribute(\'name\',\'edit\')?0:0"/>');
if (!defined('DB_HTML_EDIT')) define('DB_HTML_EDIT','Edit');
if (!defined('DB_HTML_DELETE')) define('DB_HTML_DELETE','Delete');
+
+# Create a temporary table when table is a SELECT
if (!defined('DB_TABLE_QUERY_NAME')) define('DB_TABLE_QUERY_NAME','_query_');
Class Table extends nb {
# NB 28.03.16 public $fields_keys;
public $replace = array(); # replace by javascript
public $extras = array();
- public $call_rows; # Function to call in rows()
+ public $row_parse_pre; # Function to call in rows()
public $count;
public $engine;
public $created;
# hidden, sort, ... fields
public static $params = array( 'db', 'table', 'limit', 'debug', 'action');
- public $orderby = null;
public $fields;
function __construct($name,$opt=array()) {
} elseif (isset($opt['extras'])) {
$this->add_extras($opt['extras']);
-
- # Extras should disapear - NB 29.03.16
-# NB 29.03.16 } elseif ($this->db()
-# NB 29.03.16 and isset($this->db()->extras)
-# NB 29.03.16 and isset($this->db()->extras[$this->name])
-# NB 29.03.16 ) {
-# NB 29.03.16 $this->add_extras($this->db()->extras[$this->name]);
-
+ unset($opt['extras']);
}
- unset($opt['extras']);
// Connection
#bye($opt['db']);
if (isset($opt['db'])) {
$this->db(is_object($opt['db']) ? $opt['db'] : new Db($opt['db']));
+ unset($opt['db']);
} elseif(isset($GLOBALS['Db'])) {
$this->db($GLOBALS['Db']);
} else {
$this->db(new Db());
}
- unset($opt['db']);
+
+ // Order BY
+# NB 10.04.16 if (isset($opt['orderby'])) {
+# NB 10.04.16 $this->pdef('orderby',$opt['orderby']);
+# NB 10.04.16 unset($opt['orderby']);
+# NB 10.04.16 }
// Add others
#if (empty($opt)) bye($opt);
}
- // Sort
- if ($this->orderby) $this->pset('orderby',$this->orderby);
-
# NB 29.03.16 return $this->fields();
}
public function url_sort($name) {
+ if ($this->p('buttons')==='0' or !($f=$this->fields($name)) or !empty($f->dyn)) return self::prettyText($name);
+ #debug($f);
+
# See: http://dev.w3.org/html5/html-author/charref
$html = '';
Html Output
******************************************************************/
public function rows(&$opt=array(),$opt_by_val=null) {
+ if (isset($this->orderby)) self::pdef('orderby',$this->orderby);
if ($opt_by_val !== null) $opt = $opt_by_val;
-# NB 17.03.16 $format = ( $this->p('format') ? $this->p('format') : 'table' );
-# NB 19.03.16 $format = $this->pdef('format','table');
$format = $this->p('format');
if (!$format) bye("No param format");
$count++;
- if (!empty($this->call_rows)) {
- $call = $this->call_rows; $call($row);
+ if (!empty($this->row_parse_pre)) {
+ $call = $this->row_parse_pre; $call($row);
}
if ($opt['is_html'] and !$out_conf) {
}
}
+ if (!empty($this->row_parse_post)) {
+ $call = $this->row_parse_post; $call($row);
+ }
+
#
# Head
#
if ($count === 1) {
if ($opt['is_html']) echo $this->html_rows_top();
- if ($this->call_rows) {
+ if (!empty($this->row_parse_pre) or !empty($this->row_parse_post)) {
foreach (array_keys($row) as $name) {
if (!$this->fields($name)) {
$this->fields[$name] = new Field($name);
- $this->call = true;
+ $this->fields[$name]->dyn = true;
#$fields[$name] = $this->fields[$name];
}
}
foreach ($fields as $name => $f) {
#$html .= '<th class="'.$f.'">'.($this->p('buttons')==='0' ? $f : $this->url_sort($f)).'</th>'.NB_EOL;
- $sort = $this->p('buttons')!=='0' and empty($f->call);
- $html .= '<th class="'.$name.($f->key?' key':'').'">'.(!$sort ? $this->prettyText($name) : $this->url_sort($name)).'</th>'.NB_EOL;
+ $html .= '<th class="'.$name.($f->key?' key':'').'">'.$this->url_sort($name).'</th>'.NB_EOL;
}
if ($this->p('buttons')!=='0' and DB_HTML_DELETE) $html .= '<th class="delete"></th>'.NB_EOL;
$html .= '</tr>'.NB_EOL.'</thead>'.NB_EOL;
$r .= self::form_hidden(array('db','table','format','limit','download'));
$r .= '<input type="hidden" name="download" value="0"/>'; // Embed for no html format
- // Format
+ // Tables - see default.js if you change class
$r .= '<span class="label">';
-
- #$criteria[] = html_select_array(ar_map('array($a == "html" ? "" : $a,strtoupper($a))',$this->formats));
-# NB 01.03.16 $r .= '<label for="format">Format</label>'.html_select_array(array(
-# NB 01.03.16 'table','div','csv','xml','json','yaml'
- $r .= '<label for="format">Format</label>'.html_select_array($this->db()->formats,array(
- 'html' => 'class="format" name="format" id="format"',
- 'selected' => $this->p('format'),
+ $r .= '<label for="table">Tables</label>'.html_select_array(array_keys($this->db()->tables()),array(
+ 'html' => 'class="tables" name="table" id="table"',
+ 'selected' => $this->p('table'),
'prettyText' => true,
));
$r .= '</span>';
$r .= '</span>';
}
- // Tables - see default.js if you change class
+ // Format
$r .= '<span class="label">';
- $r .= '<label for="table">Tables</label>'.html_select_array(array_keys($this->db()->tables()),array(
- 'html' => 'class="tables" name="table" id="table"',
- 'selected' => $this->p('table'),
+
+ #$criteria[] = html_select_array(ar_map('array($a == "html" ? "" : $a,strtoupper($a))',$this->formats));
+# NB 01.03.16 $r .= '<label for="format">Format</label>'.html_select_array(array(
+# NB 01.03.16 'table','div','csv','xml','json','yaml'
+ $r .= '<label for="format">Format</label>'.html_select_array($this->db()->formats,array(
+ 'html' => 'class="format" name="format" id="format"',
+ 'selected' => $this->p('format'),
'prettyText' => true,
));
$r .= '</span>';
# NB 28.03.16 'replace',
'extras',
#'params',
- 'orderby',
'count',
'engine',
'created',
'tables' => '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()',
'status' => array (
+ 'SHOW MASTER STATUS' => function(&$r) {
+ $row = array();
+ foreach ($r as $k=>$v) {
+ if (preg_match('/[A-Za-z]/',$k) and $v!=='') $row["MASTER.$k"] = $v;
+ }
+ return $row;
+ },
+ 'SHOW SLAVE STATUS' => function($r) { $row = array(); foreach (array(
+ 'Seconds_Behind_Master',
+ 'Master_Host',
+ 'Slave_IO_State',
+ 'Master_Log_File',
+ 'Read_Master_Log_Pos',
+ 'Relay_Log_File',
+ 'Relay_Log_Pos',
+ 'Relay_Master_Log_File',
+ 'Master_Server_Id',
+ ) as $k) { if (isset($r[$k])) $row["SLAVE.$k"] = $r[$k]; } return $row;
+ },
'SHOW GLOBAL STATUS' => create_function('&$r',join('',array(
'if (preg_match("/(Threads.*|Conn.*|Max_used_connections|Table_.*|Open.*_tables)/",$r["Variable_name"]))'
- .'return array("GLB.".$r[0]=>$r[1]);'
+ .'return array("GLOBAL.".$r[0]=>$r[1]);'
#'if (preg_match("/(Threads_connected|Max_used_connections|Table_locks_immediate|Table_locks_waited|Open.*_tables)/",$r[0])) return $r;',
))),
'SHOW VARIABLES' => create_function('&$r',join('',array(
- 'if (preg_match("/^(Table|.*[Cc]onn|Open|Com).*/",$r["Variable_name"]))'
- .'return array("VAR.".$r[0]=>$r[1]);'
- ))),
- 'SHOW SLAVE STATUS' => create_function('&$r',join('',array(
- 'foreach ($r as $k=>$v) {',
- 'if (!preg_match("/^(Seconds_Behind_Master)$/",$k)) unset($r[$k]);',
- '}',
- 'return $r;',
+ 'if (preg_match("/^(Table|.*[Cc]onn|Open|Com|hostname).*/",$r["Variable_name"]))'
+ .'return array("VARIABLES.".$r[0]=>$r[1]);'
))),
),
}
function prettyText($text) {
+ $replace = array(
+ '/(\w)(,)(\w)/' => '$1$2 $3',
+ '/_/' => ' ',
+ '/[^\w,]+/' => ' ',
+ );
return ucwords(
- preg_replace('/\W+/',' ',
- str_replace('_',' ',$text)
- )
+ preg_replace(array_keys($replace),array_values($replace),$text)
);
}
}
}
- public function __sleep() { return array_keys((array)$this); }
+ public function __sleep() {
+ return(get_class_vars(get_class($this))); # get all
+# NB 09.04.16 return array_keys((array)$this);
+ #debug((array)$this); # publics + private in a weird way !
+ #debug(get_object_vars($this)); # non static
+ }
#public function __wakeup() { }
public function __destruct() {
return isset($_REQUEST[$name]) ? $_REQUEST[$name] : $default;
}
+ /*
+ * Replace aliases by long name
+ */
+ public static function paliases($aliases) {
+ foreach ($aliases as $short=>$long) {
+ DB::pdef($long,Db::p($short));
+ Db::pset($short,null);
+ }
+ }
+
/*
* Set a default's param value, if not set
* Return the value set or existing
$debug = debug_backtrace(); array_shift($debug);
- $tot = count($debug);
- foreach (array_reverse($debug) as $i=>$call_info) {
+ for ($i=0;$i<$deep;$i++) {
+ array_shift($debug);
+ }
+ foreach ($debug as $i=>$call_info) {
$msg .= ( $one_line ? ($preff !=='' ? $preff : ' | ') : "\n$preff " ) . self::debug_backtrace_info($call_info);
-
- if ($deep and ($tot-$i) <= $deep+1) break;
-
}
return $msg;
}
# For sprintf
-#bye($head);
unset($o['head_max_len']);
# NB 01.04.16 if (!empty($head)) {
# NB 01.04.16 $o['head_max_len'] = max(self::ar_map('strlen($a)',$head));
#bye($row);
}
- if (!self::is_hash($row)) unset($o['head_max_len']);
- if (is_array($row) and count($row)>1) $o['head_max_len'] = strlen(count($row));
+# NB 10.04.16 if (!self::is_hash($row)) unset($o['head_max_len']);
+# NB 10.04.16 if (is_array($row) and count($row)>1) $o['head_max_len'] = strlen(count($row));
#if (!self::is_hash($row)) return out_yaml($row,$o);
# text
return $v;
}
+ public static function is_html($type=null) {
+ if ($type === null) $type = self::$type;
+ #return self::type($type,'is_html')
+ return (strpos($type,'html') !==false or (
+ !empty(self::$types[$type]['is_html'])
+ #and !empty(self::$types[$type]['is_xml'])
+ ));
+ }
+
public static function escape($v,$type=null,$charset=null) {
if ($charset === null) $type = self::$charset;
return $Page;
}
+ public function phpinfo() {
+ ob_start();
+ phpinfo(INFO_ALL - INFO_LICENSE);
+ $phpinfo = ob_get_contents();
+ ob_end_clean();
+
+ # Only tags without attrs
+ $phpinfo = preg_replace('/(<\w+)\s+[^>]+/','$1',$phpinfo);
+
+ # No anchors
+ $phpinfo = preg_replace('@</?a>@','',$phpinfo);
+
+ # Delete header that could break html columns
+ $phpinfo = preg_replace('@<tr><th>.*?</tr>@','',$phpinfo);
+
+ # Add class
+ $phpinfo = str_replace('<table>','<table class="block">',$phpinfo);
+ #$phpinfo = str_replace('<tr>','<tr class="row">',$phpinfo);
+
+ # Pretty h2
+ $phpinfo = preg_replace_callback ('@(<h2>(?:<[^>]+>)?)([^<]+)@',function($m){return $m[1].prettyText($m[2]);},$phpinfo);
+
+ if (!preg_match_all('@(<h2.*?</table>)@s',$phpinfo,$m)) return '';
+ return join("\n",$m[0]);
+ }
+
+ public function infos() {
+ $out = array(
+ 'path' => $this->path()
+ );
+ foreach (get_class_vars(get_class($this)) as $k=>$v) {
+ if (!empty($this->$k)) $out[$k] = is_scalar($this->$k) ? $this->$k : out::scalar($this->$k);
+ }
+ foreach (self::p() as $k=>$v) $out['p.'.$k] = $v;
+ #foreach ($_SERVER as $k=>$v) $out['_SERVER.'.$k] = $v;
+ #foreach ($_ENV as $k=>$v) $out['_ENV.'.$k] = $v;
+
+ $out = array_map(function($k, $v) { return array("name"=>$k,"value"=>$v); },array_keys($out),$out);
+ return $out;
+ }
+
public function action() {
$action = self::p('action');
$format = self::p('format',self::php_cli() ? 'csv' : 'table');
+ $is_html = out::is_html($format);
- if ($action == 'page.info') {
- $out = array('path' => $this->path());
- foreach (get_object_vars($this) as $k=>$v) { if (!empty($this->$k)) $out[$k] = $this->$k; }
- $out['p'] = self::p();
- $out['_SERVER'] = $_SERVER;
-
- $out = array_map(function($k, $v) { return array("name"=>$k,"value"=>$v); },array_keys($out),$out);
+ if ($action == 'page.infos') {
+ $out = $this->infos();
out::rows($format,$out);
return true;
+
+ } elseif ($action == 'page.phpinfo' or $action == 'phpinfo') {
+ echo $this->phpinfo(); return true;
+
+ } elseif (preg_match('/^page\.(\w+)/',$action,$m)) {
+#bye($this->$m[1]());
+ if ($rows = $this->$m[1]()) return $this->out2($rows,(is_scalar($rows) ? $m[1] : array()));
+
}
return false;