*****************************************************************************/
require_once(dirname(__FILE__).'/nb.php');
require_once(dirname(__FILE__).'/db/table.php');
-# NB 29.12.15 define('SQL_NAME_FORCE_QUOTE_EXP','^(range)$');
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="this.setAttribute(\'name\',\'edit\');this.parentElement.submit()?0:0"/>'
function print_header($format) {
if (empty($_SERVER['DOCUMENT_ROOT'])) return null;
- if (!$c=$this->ext2mime($format)) return false;
- header('Content-type: '.$c);
- return true;
+ if (!$mime=$this->ext2mime($format)) return false;
+ header('Content-type: '.$mime);
+ return $mime;
}
function html_menu($table=null) {
}
function sql_name($value) {
-# NB 29.12.15 if (preg_match('/^\w+$/',$value) and
-# NB 29.12.15 (
-# NB 29.12.15 !SQL_NAME_FORCE_QUOTE_EXP or
-# NB 29.12.15 !preg_match('/'.SQL_NAME_FORCE_QUOTE_EXP.'/',$value)
-# NB 29.12.15 )
-# NB 29.12.15 ) return $value;
if ($this->type == 'mysql') return '`'.$value.'`';
return '"'.$value.'"';
}
+ function out($v) {
+ $f = $this->p('format','json');
+ #if (preg_match('/yaml|yml/',$f)) bye($this->yaml_encode($this->object2array($this->fields())));
+ $mime = $this->print_header($f);
+
+ #echo $v.PHP_EOL;
+ #bye($f); return true;
+ if ($f == 'json') { echo json_encode($v).PHP_EOL; }
+ elseif (preg_match('/yaml|yml/',$f)) { echo $this->yaml_encode($v); }
+ elseif (preg_match('/php|var_export/',$f)) { echo var_export($v,true); }
+ elseif (preg_match('/var_dump/',$f)) { echo var_dump($v,true); }
+ elseif (is_scalar($v)) { echo($v.PHP_EOL); }
+ //else { echo($v.PHP_EOL); }
+ else{ echo var_export($v,true); }
+
+ return true;
+
+ }
+
function action($table) {
if ($this->p('format') == 'table') $this->pset('format','');
$action = $this->p('action');
- $formated = $this->print_header($this->p('format'));
- $data = null;
-
if ($action == 'tables') {
- $this->print_header('json');
- $data = $this->tables();
- echo json_encode($data);
- return true;
-
- } elseif ($action == 'fields') {
- $this->print_header('json');
- $data = $table->fields();
- echo json_encode($data);
- return true;
+ return $this->out($this->tables());
} elseif ($action == 'html_menu') {
+ $this->print_header($this->p('format','html'));
echo $this->html_menu();
return true;
} else {
- if ($table->action()) return true;
+ if ($r=$table->action()) return $r;
}
if (!defined('DB_HTML_EDIT')) define('DB_HTML_EDIT','Edit');
if (!defined('DB_HTML_DELETE')) define('DB_HTML_DELETE','Delete');
-if (!defined('DB_HTML_NAV_TOP')) define('DB_HTML_NAV_TOP','<div class="nav" id="nav_top"></div>'.PHP_EOL);
if (!defined('DB_TABLE_QUERY_NAME')) define('DB_TABLE_QUERY_NAME','_query_');
class table extends nb {
public $fields_keys = null;
public $replace = array(); # replace by javascript
public $extras = array();
- public $params = array(
+ public $params = array( # hidden, sort, ... fields
'table',
'limit',
'debug',
+ 'action',
);
public $order_by = null;
$this->name = $name;
// Extras
- if (isset($opt['extras'])) {
+ if ($this->p('extras')==='0') {
+ $this->extras = array();
+
+ } else if (isset($opt['extras'])) {
$this->add_extras($opt['extras']);
} elseif (
*/
function sql() {
if (isset($this->sql)) return $this->sql;
+
+ if (!preg_match('/^[\w_-]+$/',$this->name) ) {
+ $this->sql = $this->name;
+ return $this->sql;
+ }
+
if ($this->db->type == 'sqlite') {
$sql = "SELECT sql FROM sqlite_master WHERE name='$this->name'";
} elseif ($this->db->type == 'mysql') {
$sql = "SHOW CREATE TABLE `$this->name`";
} elseif ($this->db->type == 'pgsql') {
$sql = "SELECT show_create_table('$this->name')";
+ $sql = "
+SELECT
+ 'CREATE TABLE '||sql.table||'('
+ ||array_to_string(array_agg(sql),', ')
+ ||')' 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 = 'r'::char
+ 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='$this->name'
+GROUP BY sql.id,sql.table
+";
} else {
err('table.sql(): Unknow db type: '.$this->db->type);
}
#bye($row);
$field = array(
'name' => $row['name'],
- 'extra' => null,
+ 'extra' => null, # !!! nothing todo with class variable $extras
'type' => strtolower($row['type']),
'default' => null,
'key' => null,
$next = 999999;
}
- #$html .= '<div id="nav_bottom">';
-
if ($prev>=0) $html .= '<span class="prev"><a href="'.$this->url_list('limit',preg_replace('/^0,/','',"$prev,$y")).'"><<</a></span> ';
$html .= '<span class="count">'.($tot ? ($x+1) : 0).' - '.( $count<($x+$y) ? $count : ($x+$y) ).' / '.$tot.' results</span>';
if ($next<$tot) $html .= ' <span class="prev"><a href="'.$this->url_list('limit',"$next,$y").'">>></a></span>';
- #$html .= '</div>'.PHP_EOL;
- static $js = null;
- if ($js === null) {
- $html .= '<script type="text/javascript"><!-- '.PHP_EOL
- ."var rb = document.getElementById('nav_bottom'); var rt = document.getElementById('nav_top'); if (rb && rt) rt.innerHTML = rb.innerHTML;\n"
- . ' --></script>'.PHP_EOL
- ;
- $js = '1';
- }
-
return $html;
}
if (!$this->extras) return '';
$select = array(); foreach ($this->extras as $k => $v) {
- $select[] = $v->extra." AS ".$v->quote($k,true);
+# NB 27.02.16 $select[] = $v->extra." AS ".$v->quote($k,true);
+ $select[] = $v->extra." AS ".$this->sql_name($k);
}
return ','.join(',',$select);
$sql = "SELECT$select_count *" . $this->select_extras();
$sql .= " FROM ".$this->sql_name();
-
- $this->sql = $sql = $sql . $where;
+ $sql .= $where;
if ($this->p('sort')) $sql .= ' ORDER BY '.$this->p('sort');
//
// Get results
//
+ $this->sql = $sql;
$this->debug($sql,1);
$st = $this->db->conn->prepare($sql);
$st->execute();
$format = ( $this->p('format') ? $this->p('format') : 'table' );
- if (!isset($opt['is_html'])) $opt['is_html'] = preg_match('/^(table|div)$/',$format) ? true : false;
+ if (!isset($opt['is_html'])) $opt['is_html'] = preg_match('/^(table|div)$/',$format)
+ ? ( $this->p('header')!=="0" and $this->p('inc')!=="1")
+ : false
+ ;
- if (preg_match('/^(1)?$/',$this->p('header'))) echo $this->{"rows_begin_$format"}($this->fields());
+ if ($opt['is_html']) echo $this->html_nav_top();
+ echo $this->{"rows_begin_$format"}($this->fields());
$count = 0;
while ($row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {
$opt['count'] = $count;
$opt['limit'] = $limit;
echo $this->{"rows_end_$format"}($opt);
- if ($opt['is_html']) echo '<div id="nav_bottom" class="nav bottom">'
+
+ if ($opt['is_html']) echo '<div class="nav bottom">'
.$this->nav($opt['count'],$opt['tot'],$opt['limit'])
.'</div>'
.PHP_EOL;
-----------------------------------------------------------------*/
function rows_begin_json() {
$this->_row_json = null;
+ return '['.PHP_EOL;
return ''
."// database: ".$this->db->name."\n"
."// table: $this->name\n"
}
function rows_rec_json(&$row) {
- $json = '';
if ($this->_row_json === null) {
+ $json = '';
$this->_row_json = true;
} else {
- $json .= ',';
+ $json = ','.PHP_EOL;
}
- return $json . json_encode($row).PHP_EOL;
+ return $json . json_encode($row);
}
function rows_end_json() {
unset($this->_row_json);
- return ']'.PHP_EOL;
+ return PHP_EOL.']'.PHP_EOL;
}
/*-----------------------------------------------------------------
Csv
-----------------------------------------------------------------*/
function rows_begin_csv($fields) {
+
+ if ($this->p('header')==="0") return '';
return join("\t",array_keys($fields))."\n";
}
-----------------------------------------------------------------*/
function rows_begin_table($fields) {
- $html = $this->html_nav_top();
+ $html = '';
+
#$html .= '<table data-role="table" class="ui-responsive rows '.$this->name.'">'.PHP_EOL;
$html .= '<table class="rows '.$this->name.'">'.PHP_EOL;
#if (!empty($opt)) $html .= '<caption>' . $this->nav($opt['count'],$opt['tot'],$opt['limit']) . '</caption>' .PHP_EOL;
- $html .= '<thead><tr class="head">';
+ if ($this->p('header')!=="0") {
+ $html .= '<thead>'.PHP_EOL.'<tr class="head">'.PHP_EOL;
- if (DB_HTML_EDIT) $html .= '<th class="edit"></th>';
+ if ($this->p('buttons')!=='0' and DB_HTML_EDIT) $html .= '<th class="edit"></th>'.PHP_EOL;
- foreach (array_keys($fields) as $f) {
- $html .= '<th class="'.$f.'">'.$this->url_sort($f).'</th>';
+ foreach (array_keys($fields) as $f) {
+ #$html .= '<th class="'.$f.'">'.($this->p('buttons')==='0' ? $f : $this->url_sort($f)).'</th>'.PHP_EOL;
+ $html .= '<th class="'.$f.'">'.($this->p('buttons')==='0' ? $this->prettyText($f) : $this->url_sort($f)).'</th>'.PHP_EOL;
+ }
+ if ($this->p('buttons')!=='0' and DB_HTML_DELETE) $html .= '<th class="delete"></th>'.PHP_EOL;
+ $html .= '</tr>'.PHP_EOL.'</thead>'.PHP_EOL;
}
- if (DB_HTML_DELETE) $html .= '<th class="delete"></th>';
- $html .= '</tr></thead><tbody>'.PHP_EOL;
+ $html .= '<tbody>'.PHP_EOL;
return $html;
}
function rows_rec_table(&$row) {
- $html = '<tr class="row">';
+ $html = '<tr class="row">'.PHP_EOL;
- $html .= '<td class="action"><a class="edit button" href="'.$this->url_keys($row,'action=edit').'">'.DB_HTML_EDIT.'</a></td>';
+ if ($this->p('buttons')!=='0') $html .=
+ '<td class="action"><a class="edit button" href="'
+ .$this->url_keys($row,'action=edit')
+ .'">'.DB_HTML_EDIT.'</a></td>'.PHP_EOL;
foreach ($row as $k => $v) {
- $html .= '<td class="'.$k.'">'.$v.'</td>';
+ if (isset($this->extras[$k])) $k .= " extra";
+ $html .= '<td class="'.$k.'">'.$v.'</td>'.PHP_EOL;
}
- $html .= '<td class="action"><a class="delete button" href="'.$this->url_keys($row,'action=delete').'">'.DB_HTML_DELETE.'</a></td>';
+ if ($this->p('buttons')!=='0') $html .=
+ '<td class="action"><a class="delete button" href="'
+ .$this->url_keys($row,'action=delete')
+ .'">'.DB_HTML_DELETE.'</a></td>'.PHP_EOL;
+
$html .= '</tr>'.PHP_EOL;
return $html;
Html Div
-----------------------------------------------------------------*/
function rows_begin_div() {
- return '<div class="rows '.$this->name.'">'.PHP_EOL.$this->html_nav_top();
+ return '<div class="rows '.$this->name.'">';
}
function rows_rec_div(&$row) {
$html .= '<ul class="row">';
- $html .= '<li class="buttons">';
- $html .= '<a class="edit button" href="'.$this->url_keys($row,'action=edit').'">'.DB_HTML_EDIT.'</a>';
- $html .= '<a class="delete button" href="'.$this->url_keys($row,'action=delete').'">'.DB_HTML_DELETE.'</a>';
- $html .= '</li>';
+ if ($this->p('buttons')!=='0') {
+ $html .= '<li class="buttons">';
+ $html .= '<a class="edit button" href="'.$this->url_keys($row,'action=edit').'">'.DB_HTML_EDIT.'</a>';
+ $html .= '<a class="delete button" href="'.$this->url_keys($row,'action=delete').'">'.DB_HTML_DELETE.'</a>';
+ $html .= '</li>';
+ }
foreach ($row as $k => $v) {
$html .= '<li>'
$html .= '</ul>'.PHP_EOL;
-// NB 03.08.15 $html .= '<div class="buttons">';
-// NB 03.08.15 $html .= '<a class="edit button" href="'.$this->url_keys($row,'action=edit').'">'.DB_HTML_EDIT.'</a>';
-// NB 03.08.15 $html .= '<a class="delete button" href="'.$this->url_keys($row,'action=delete').'">'.DB_HTML_DELETE.'</a>';
-// NB 03.08.15 $html .= '</div>';
-
-
return $html;
}
function rows_end_div($opt=array()) {
}
- function sql_name() {
- return $this->db->sql_name($this->name);
+ function sql_name($value=null) {
+ return $this->db->sql_name($value === null ? $this->name : $value);
}
function insert($hvalues) {
return $this->db->exec($sql);
}
+ function out($v) { return $this->db->out($v); }
+
function action() {
$action = $this->p('action');
if ($action == 'fields') {
- $this->db->print_header('json');
- $data = $this->fields();
- echo json_encode($data);
- return true;
+ return $this->out($this->object2array($this->fields()));
+
+ } elseif ($action == 'sql') { return $this->out($this->sql());
+ } elseif ($action == 'count') { return $this->out($this->count());
+
+ } elseif ($action == 'rows') {
+ #if ($this->p('page')==='0') $this->pset('inc',1);
+ return $this->rows();
+
+ } elseif ($action == 'table') {
+ return $this->out(array(
+ #"count" => $this->count(),
+ "sql_name" => $this->sql_name(),
+ "sql" => $this->sql(),
+ "fields" => $this->object2array($this->fields()),
+ ));
} elseif ($action == 'delete') {
if (!$this->delete($this->p(),$e)) bye($e);
}
function html_nav_top() {
- $html = DB_HTML_NAV_TOP;
+ if ($this->p('header')==="0") return '';
+ $html = '';
+
if (!empty($this->replace)) {
+
$replace = array();
foreach ($this->replace as $k=>$v) { $replace[] = "$k.$v"; }
- $html .= '<span id="db-table-replace" style="display:none">'.join(' ',$replace).'</span>';
+ $html .= '<span id="db-table-replace" style="display:none">'.join(' ',$replace).'</span>'.PHP_EOL;
+
}
+
return $html;
+
+ }
+
+ function count() {
+
+ if (isset($this->count)) return $this->count;
+ $sql_count = $this->name;
+ if (preg_match('/^[\w_-]+$/',$sql_count)) {
+ $sql_count = "SELECT count(*) FROM ".$this->sql_name($sql_count);
+
+ } else {
+ $sql_count = preg_replace('/ (ORDER|LIMIT) .*?$/s','',$sql_count);
+ $sql_count = preg_replace('/^SELECT .*FROM/s','SELECT count(*) FROM ',$sql_count);
+
+ }
+
+ $this->count = (int)$this->db->row($sql_count);
+ return $this->count;
}
}