version() > '4.1' ? 'Engine' : 'Type'; $tablepre = $_G['config']['db'][1]['tablepre']; $dbcharset = $_G['config']['db'][1]['dbcharset']; $backupdir = C::t('setting')->fetch('backupdir'); if(!$backupdir) { $backupdir = random(6); @mkdir('./data/backup_'.$backupdir, 0777); C::t('setting')->update('backupdir',$backupdir); } $backupdir = 'backup_'.$backupdir; if(!is_dir('./data/'.$backupdir)) { mkdir('./data/'.$backupdir, 0777); } global $excepttables; $excepttables=array(); $filename=date('ymd').'_'.random(8); DB::query('SET SQL_QUOTE_SHOW_CREATE=0', 'SILENT'); $tables = arraykeys2(fetchtablelist($tablepre), 'Name'); $memberexist = array_search(DB::table('user'), $tables); if($memberexist !== FALSE) { unset($tables[$memberexist]); array_unshift($tables, DB::table('user')); } $time = dgmdate(TIMESTAMP); $success=false; global $complete,$startrow; $startrow=0; $volume=0;$tableid = 0;$startfrom = 0; while(!$success){ $volume += 1; $idstring = '# Identify: '.base64_encode("$_G[timestamp],".$_G['setting']['version'].",dzz,multivol,{$volume},{$tablepre},{$dbcharset}")."\n"; $dumpcharset = str_replace('-', '', $_G['charset']); $backupfilename = './data/'.$backupdir.'/'.str_replace(array('/', '\\', '.', "'"), '', $filename); $sqldump = ''; $startfrom=$startrow; if(!$tableid && $volume == 1) { foreach($tables as $table) { $sqldump .= sqldumptablestruct($table); } } $complete = TRUE; for(; $complete && $tableid < count($tables) && strlen($sqldump) + 500 < 2048 * 1000; $tableid++) { $sqldump .= sqldumptable($tables[$tableid], $startfrom, strlen($sqldump)); if($complete) { $startfrom = 0; } } $dumpfile = $backupfilename."-%s".'.sql'; !$complete && $tableid--; if(trim($sqldump)) { $sqldump = "$idstring". "# \n". "# DzzOffice Multi-Volume Data Dump Vol.$volume\n". "# Version: DzzOffice! ".$_G['setting']['version']."\n". "# Time: $time\n". "# Type: dzz\n". "# Table Prefix: $tablepre\n". "#\n". "# Dzz! Home: http://www.dzzoffice.com\n". "# Please visit our website for newest infomation about DzzOffice\n". "# --------------------------------------------------------\n\n\n". $sqldump; $dumpfilename = sprintf($dumpfile, $volume); @$fp = fopen($dumpfilename, 'wb'); @flock($fp, 2); if(@!fwrite($fp, $sqldump)) { @fclose($fp); runlog('database_export','database_export_file_invalid',1); } else { fclose($fp); unset($sqldump, $zip, $content); continue; } } else { $success=true; C::t('cache')->insert(array( 'cachekey' => 'db_export', 'cachevalue' => serialize(array('dateline' => $_G['timestamp'])), 'dateline' => $_G['timestamp'], ), false, true); } } function fetchtablelist($tablepre = '') { global $db; $arr = explode('.', $tablepre); $dbname = $arr[1] ? $arr[0] : ''; $tablepre = str_replace('_', '\_', $tablepre); $sqladd = $dbname ? " FROM $dbname LIKE '$arr[1]%'" : "LIKE '$tablepre%'"; $tables = $table = array(); $query = DB::query("SHOW TABLE STATUS $sqladd"); while($table = DB::fetch($query)) { $table['Name'] = ($dbname ? "$dbname." : '').$table['Name']; $tables[] = $table; } return $tables; } function arraykeys2($array, $key2) { $return = array(); foreach($array as $val) { $return[] = $val[$key2]; } return $return; } function sqldumptablestruct($table) { global $_G, $db, $excepttables; if(in_array($table, $excepttables)) { return; } $createtable = DB::query("SHOW CREATE TABLE $table", 'SILENT'); if(!DB::error()) { $tabledump = "DROP TABLE IF EXISTS $table;\n"; } else { return ''; } $create = $db -> fetch_row($createtable); if (strpos($table, '.') !== FALSE) { $tablename = substr($table, strpos($table, '.') + 1); $create[1] = str_replace("CREATE TABLE $tablename", 'CREATE TABLE ' . $table, $create[1]); } $tabledump .= $create[1]; $tablestatus = DB::fetch_first("SHOW TABLE STATUS LIKE '$table'"); $tabledump .= (($tablestatus['Auto_increment'] && (strpos($tabledump,'AUTO_INCREMENT')===false))? " AUTO_INCREMENT=$tablestatus[Auto_increment]" : ''). ";\n\n"; if ($_GET['sqlcompat'] == 'MYSQL40' && $db -> version() >= '4.1' && $db -> version() < '5.1') { if ($tablestatus['Auto_increment'] <> '') { $temppos = strpos($tabledump, ','); $tabledump = substr($tabledump, 0, $temppos) . ' auto_increment' . substr($tabledump, $temppos); } if ($tablestatus['Engine'] == 'MEMORY') { $tabledump = str_replace('TYPE=MEMORY', 'TYPE=HEAP', $tabledump); } } return $tabledump; } function sqldumptable($table, $startfrom = 0, $currsize = 0) { global $_G, $startrow, $dumpcharset, $complete, $excepttables; $db = & DB::object(); $offset = 300; $tabledump = ''; $tablefields = array(); $_GET['usehex']=TRUE; $query = DB::query("SHOW FULL COLUMNS FROM $table", 'SILENT'); if(strexists($table, 'adminsessions')) { return ; } elseif(!$query && DB::errno() == 1146) { return; } elseif(!$query) { $_GET['usehex'] = FALSE; } else { while($fieldrow = DB::fetch($query)) { $tablefields[] = $fieldrow; } } if(!in_array($table, $excepttables)) { $tabledumped = 0; $numrows = $offset; $firstfield = $tablefields[0]; while($currsize + strlen($tabledump) + 500 < 2048 * 1000 && $numrows == $offset) { if($firstfield['Extra'] == 'auto_increment') { $selectsql = "SELECT * FROM $table WHERE $firstfield[Field] > $startfrom ORDER BY $firstfield[Field] LIMIT $offset"; } else { $selectsql = "SELECT * FROM $table LIMIT $startfrom, $offset"; } $tabledumped = 1; $rows = DB::query($selectsql); $numfields = $db->num_fields($rows); $numrows = DB::num_rows($rows); while($row = $db->fetch_row($rows)) { $comma = $t = ''; for($i = 0; $i < $numfields; $i++) { $t .= $comma.($_GET['usehex'] && !empty($row[$i]) && (strexists($tablefields[$i]['Type'], 'char') || strexists($tablefields[$i]['Type'], 'text')) ? '0x'.bin2hex($row[$i]) : '\''.$db->escape_string($row[$i]).'\''); $comma = ','; } if(strlen($t) + $currsize + strlen($tabledump) + 500 < 2048 * 1000) { if($firstfield['Extra'] == 'auto_increment') { $startfrom = $row[0]; } else { $startfrom++; } $tabledump .= "INSERT INTO $table VALUES ($t);\n"; } else { $complete = FALSE; break 2; } } } $startrow = $startfrom; $tabledump .= "\n"; } return $tabledump; } ?>