class Pman_Admin_Dump extends Pman {
+ static $cli_desc = "Dump database ?/ needs more info...";
+
+
function getAuth()
{
var $deps = array(); // list of dependants
var $out = array(); // list of created sql/shell scripts.
- function get($path )
+ function get($path, $opts = Array() )
{
+ ini_set('memory_limit', '256M'); // we need alot of memory
+ set_time_limit(0);
+
$argv = $_SERVER['argv'];
array_shift($argv);
array_shift($argv);
- $opts = explode(',', 'table==,where==,dump-dir==');
+ $opts = explode(',', 'table==,where==,dump-dir==,debug=');
require_once 'Console/Getopt.php';
$go = Console_Getopt::getopt2($argv, '', $opts );
if (is_object($go)) {
}
$errs = array();
foreach($opts as $req) {
+ if (substr($req,-2, 2) != '==') { // skip optional arguments
+ continue;
+ }
if (empty($args[substr($req,0, -2)])) {
$errs[] = "--".substr($req,0, -2) . ' is required';
}
if (!empty($errs)) {
die(print_R($errs,true));
}
-
+ if (!empty($args['debug'])) {
+ DB_DataObject::debugLevel($args['debug']);
+ }
$this->args = $args;
$this->out = array();
$this->discoverChildren($this->args['table'], $this->args['where'], true);
$this->generateInsert();
$this->generateDelete();
$this->generateShell();
-
- echo "GENERATED FILES:";
- print_r($out);
+
+ echo "DELETING:\n";
+ foreach($this->deletes as $tbl => $ar) {
+ if (empty($ar)) { continue; }
+ echo " " .$tbl . ' -> ' . count(array_keys($ar)) . " Records\n";
+ }
+ echo "DUMPING:\n";
+ foreach($this->dumps as $tbl => $ar) {
+ if (empty($ar)) { continue; }
+ echo " " .$tbl . ' -> ' . count(array_keys($ar)) . " Records\n";
+ }
+ echo "FILES:\n";
+ echo " Total : " . $this->filetotal . " files using " . floor($this->filesize/1000000) . "Mb\n";
+
+ echo "GENERATED FILES:\n";
+ // summary
+ echo " ". implode("\n ", $this->out). "\n";
+
+
exit;
var $deletes = array(); // TABLE => [key] => TRUE|FALSE
var $dumps = array(); // TABLE => [key] => TRUE|FALSE - if it's been scanned..
var $dscan = array(); // TABLE:COL => [value => TRUE|FALSE] - if its been scanned..
+ var $childfiles = array(); // array of [ 'sourcedirectory' , 'subdirectory(s) and filename' ]
+ var $childthumbs = array(); // array of [ 'filename', 'filename' ,......]
+ var $filesize = 0; // size of files to be saved. (not total deletd..)
+ var $filetotal = 0; // number of distinct files to be saved (not total deleted)
/**
* scan table for
* a) what depends on it (eg. child elements) - which will be deleted.
}
}
+ $x->free();
// flag as checked if we where given an array.. - as some links might have been broken.
if (is_array($where)) {
foreach($where as $k) {
function discoverChildren($table, $where, $col=false )
{
+ echo "discoverChildren:$table:$col:". (is_array($where) ? (count($where) . " children" ): $where ). "\n";
global $_DB_DATAOBJECT;
$do = DB_DataObject::factory($table);
if (PEAR::isError($do)) {
if (isset($this->dumps[$table])) {
unset($this->dumps[$table]); // links to non-existant tables..
}
+ echo "SKIPPING invalid table $table\n";
return;
}
if (!isset($this->dumps[$table])) {
static $children = array();
if (!isset($children[$table])) {
-
+ $children[$table] = array();
// force load of linsk
$do->links();
foreach($_DB_DATAOBJECT['LINKS'][$do->database()] as $tbl => $links) {
}
}
+ print_R($children);
}
- if (empty($children[$table])) {
- // BLANK deletes???
- return;
- }
- // DB_DataObject::debugLevel(1);
+
$do->selectAdd();
$key = $keys[0];
$do->selectAdd($key);
- $do->find();
+ echo "GOT ". $do->find() ." results\n";
+ //DB_DataObject::debugLevel(0);
while ($do->fetch()) {
$this->dumps[$table][$do->$key] = 0;
if (!isset($this->deletes[$table][$do->$key])) {
$this->deletes[$table][$do->$key] = 0;
}
-
+
foreach($children[$table] as $kv=>$t) {
if (!isset($this->dscan[$kv])) {
$this->dscan[$kv] = array();
}
}
}
-
-
+ $do->free();
+
// now iterate throught dependants. and scan them.
$target = $this->args['dump-dir'] .'/'. date('Y-m-d').'.delete.sql';
$this->out[] = $target;
$fh = fopen($target, 'w');
+
+
+
foreach($this->deletes as $tbl=>$ar) {
+
$do = DB_DataObject::factory($tbl);
+ $tbl = $do->tableName();
$keys = $do->keys();
$key = $keys[0];
- foreach($ar as $id => $deleted) {}
+ $do->whereAddIn($keys[0] , array_keys($ar), 'int');
+ $do->find();
+ $archivePaths = method_exists($do,'archivePaths');
+ $listThumbs = method_exists($do,'listThumbs');
+ while ($do->fetch()) {
+
+ if ($archivePaths) {
+ $ct = $do->archivePaths();
+ if ($ct) {
+ $this->childfiles[] = $ct;
+ }
+ }
+ if ($listThumbs) {
+ $ct = $do->listThumbs();
+ if($ct) {
+ $this->childthumbs[] = $ct;
+ }
+ }
+ $id = $do->$key;
+
fwrite($fh, "DELETE FROM `$tbl` WHERE `$key` = $id;\n"); // we assume id's and nice column names...
}
+ $do->free();
}
fclose($fh);
}
function generateShell() {
-
+ if (empty($this->childfiles) && empty($this->childthumbs)) {
+ return;
+ }
$target = $this->args['dump-dir'] .'/'. date('Y-m-d').'.copy.sh';
$this->out[] = $target;
$fh = fopen($target, 'w');
$this->out[] = $target;
$fh3 = fopen($target, 'w');
-
- foreach($this->childfiles as $s=>$v) {
- fwrite($fh,"mkdir -p " . escapeshellarg(dirname($args['dump-dir'] .'/'.$v[1])) ."\n" );
- fwrite($fh,"cp " . escapeshellarg($v[0].'/'.$v[1]) . ' ' . escapeshellarg($args['dump-dir'] .'/'.$v[1]) ."\n" );
+
+ $done = array();
+ $donedir = array();
+ foreach($this->childfiles as $v) {
- fwrite($fh3,"mkdir -p " . escapeshellarg(dirname($v[0].'/'.$v[1])) ."\n" );
- fwrite($fh3,"cp " . escapeshellarg($args['dump-dir'] .'/'.$v[1]) . ' ' . escapeshellarg($v[0].'/'.$v[1]) . "\n" );
+ if (isset($done[$v[1]])) {
+ continue;
+ }
+ $done[$v[1]] = true;
+
+ $this->filesize += filesize($v[0].'/'.$v[1]);
+ $this->filetotal++;
+ $fdir = dirname($this->args['dump-dir'] .'/'.$v[1]);
+ if (!isset($donedir[$fdir])) {
+ fwrite($fh,"mkdir -p " . escapeshellarg(dirname($this->args['dump-dir'] .'/'.$v[1])) ."\n" );
+ }
+ fwrite($fh,"cp " . escapeshellarg($v[0].'/'.$v[1]) . ' ' . escapeshellarg($this->args['dump-dir'] .'/'.$v[1]) ."\n" );
+ if (!isset($donedir[$fdir])) {
+ fwrite($fh3,"mkdir -p " . escapeshellarg(dirname($v[0].'/'.$v[1])) ."\n" );
+ }
+ $donedir[$fdir] = true;
+
+ fwrite($fh3,"cp " . escapeshellarg($this->args['dump-dir'] .'/'.$v[1]) . ' ' . escapeshellarg($v[0].'/'.$v[1]) . "\n" );
fwrite($fh2,"rm " . escapeshellarg($v[0].'/'.$v[1]) ."\n" );
}
fclose($fh);
fclose($fh3); // restore does not need to bother with thumbnails.
+
-
- foreach($this->childthumbs as $s=>$v) {
+ foreach($this->childthumbs as $v) {
foreach($v as $vv) {
fwrite($fh2,"rm " . escapeshellarg($vv). "\n");
}
$this->out[] = $target;
$fh = fopen($target,'w');
-
-
+
foreach($this->dumps as $tbl => $ar) {
if (empty($ar)) {
continue;
}
- $do = DB_DataObject::factory($table);
+ $do = DB_DataObject::factory($tbl);
$keys = $do->keys();
- $do->whereAddIn($keys[0] , $ar, 'int');
+ $do->whereAddIn($keys[0] , array_keys($ar), 'int');
$do->find();
while ($do->fetch()) {
fwrite($fh,$this->toInsert($do));
}
-
+ $do->free();
}
fclose($fh);
/**
* toInsert - does not handle NULLS...
*/
- function toInsert($do, $ar)
+ function toInsert($do)
{
$kcol = array_shift($do->keys());
// for auto_inc column we need to use a 'set argument'...
$items = $do->table();
//print_R($items);
- $quoteIdentifiers = true; //!empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
+
// for
$leftq = '';
$rightq = '';
+ $table = $do->tableName();
foreach( $items as $k=>$v)
$rightq .= ', ';
}
- $leftq .= ($quoteIdentifiers ? ($DB->quoteIdentifier($k) . ' ') : "$k ");
+ $leftq .= '`' . $k . '`';
}
$rightq .= ' ' . intval($do->$k) . ' ';
}
- $table = ($quoteIdentifiers ? $DB->quoteIdentifier($do->__table) : $do->__table);
- return "INSERT INTO {$table} ($leftq) VALUES ($rightq);\n";
+
+ return "INSERT INTO `{$table}` ($leftq) VALUES ($rightq);\n";
}