static function load($source, $schema) { list($driver, $dsn, $dbname, $username, $password) = self::parse_dsn($source); Modyllic_Status::$source_name = $dsn; $class = self::db_driver($driver); $dbh = new PDO($dsn, $username, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => true)); call_user_func(array($class, 'load'), $dbh, $dbname, $schema); }
static function status($pos, $len) { if (self::$in_file != self::$source_name) { if (self::$in_file != "") { self::clear_progress(); } self::verbose("Loading " . self::$source_name . "...\n"); self::$in_file = self::$source_name; } if (!self::$progress) { return; } $progress_size = 2; $min_width = 8 + 2 + $progress_size + 2 + 5 + 1; # "%" $min_filename_length = 3; # if there's no way to fit the progress bar on this screen, just return if ($min_width + $min_filename_length >= self::$width) { self::$progress = false; return; } $filename = self::$source_name; # if we can fit the entire filename on the line then we size the progress bar if ($min_width + strlen(self::$source_name) < self::$width - 1) { $progress_size = self::$width - ($min_width + strlen($filename) + 1); } else { $filename = substr($filename, 0, self::$width - ($min_width + 1)); } $percent_per_file = 1 / self::$source_count; $already_done = (self::$source_index - 1) * $percent_per_file; $in_file = $len == 0 ? 1 : $pos / $len; $overall = $already_done + $percent_per_file * $in_file; $fill_count = floor($overall * $progress_size); $blank_count = ceil($progress_size - $fill_count); $fill = str_repeat("*", $fill_count); $blank = str_repeat("-", $blank_count); self::warn(sprintf("\rLoading %s [%s%s] %2.1f%%", $filename, $fill, $blank, $overall * 100)); }
static function load(array $sources, $schema = null) { if (!isset($schema)) { $schema = new Modyllic_Schema(); } Modyllic_Status::$source_count += count($sources); foreach ($sources as $source) { // Strip trailing slashes from directory names if (substr($source, -1) == "/") { $source = substr($source, 0, -1); } Modyllic_Status::$source_name = $source; Modyllic_Status::$source_index++; list($source, $loader) = self::determine_loader($source); if (isset($loader)) { call_user_func(array($loader, 'load'), $source, $schema); } else { throw new Modyllic_Loader_Exception("Could not load {$source}, file or directory not found"); } Modyllic_Status::status(1, 1); } $schema->load_sqlmeta(); return $schema; }
/** * @returns Modyllic_Schema */ static function load(PDO $dbh, $dbname, $schema) { $dbh->exec("USE information_schema"); $dbschema = self::selectrow($dbh, "SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM SCHEMATA WHERE SCHEMA_NAME=?", array($dbname)); if (!$dbschema) { throw new Exception("Database {$dbname} does not exist"); } $parser = new Modyllic_Parser(); if ($schema->name_is_default) { $schema->set_name($dbschema['SCHEMA_NAME']); $schema->charset = $dbschema['DEFAULT_CHARACTER_SET_NAME']; $schema->collate = $dbschema['DEFAULT_COLLATION_NAME']; } $table_sth = self::query($dbh, "SELECT TABLE_NAME FROM TABLES WHERE TABLE_SCHEMA=? AND TABLE_TYPE='BASE TABLE'", array($dbname)); $tables = array(); while ($table_row = $table_sth->fetch(PDO::FETCH_ASSOC)) { Modyllic_Status::$source_count++; $table = self::selectrow($dbh, "SHOW CREATE TABLE " . Modyllic_SQL::quote_ident($dbname) . "." . Modyllic_SQL::quote_ident($table_row['TABLE_NAME'])); $tables[$table_row['TABLE_NAME']] = $table['Create Table']; } $routine_sth = self::query($dbh, "SELECT ROUTINE_TYPE, ROUTINE_NAME FROM ROUTINES WHERE ROUTINE_SCHEMA=?", array($dbname)); $routines = array(); while ($routine = $routine_sth->fetch(PDO::FETCH_ASSOC)) { Modyllic_Status::$source_count++; if ($routine['ROUTINE_TYPE'] == 'PROCEDURE') { $proc = self::selectrow($dbh, "SHOW CREATE PROCEDURE " . Modyllic_SQL::quote_ident($dbname) . "." . Modyllic_SQL::quote_ident($routine['ROUTINE_NAME'])); $routines[$routine['ROUTINE_NAME']] = $proc['Create Procedure']; } else { if ($routine['ROUTINE_TYPE'] == 'FUNCTION') { $func = self::selectrow($dbh, "SHOW CREATE FUNCTION " . Modyllic_SQL::quote_ident($dbname) . "." . Modyllic_SQL::quote_ident($routine['ROUTINE_NAME'])); $routines[$routine['ROUTINE_NAME']] = $func['Create Function']; } else { throw new Exception("Unknown routine type " . $routine['ROUTINE_TYPE'] . " for " . $routine['ROUTINE_NAME']); } } } foreach ($tables as $table_name => $table_sql) { Modyllic_Status::$source_name = "{$dbname}." . $table_name; $parser->partial($schema, $table_sql, "{$dbname}.{$table_name}"); Modyllic_Status::$source_index++; } ksort($schema->tables); foreach ($routines as $routine_name => $routine_sql) { Modyllic_Status::$source_name = "{$dbname}.{$routine_name}"; $parser->partial($schema, $routine_sql, "{$dbname}.{$routine_name}"); Modyllic_Status::$source_index++; } ksort($schema->routines); if (isset($schema->tables['SQLMETA'])) { $table = $schema->tables['SQLMETA']; $meta_sth = self::query($dbh, "SELECT kind,which,value FROM " . Modyllic_SQL::quote_ident($dbname) . ".SQLMETA"); while ($meta = $meta_sth->fetch(PDO::FETCH_ASSOC)) { $table->add_row($meta); } } $schema->load_sqlmeta(); // Look for data to load... foreach ($schema->tables as $name => $table) { if ($table->static) { $data_sth = self::query($dbh, "SELECT * FROM " . Modyllic_SQL::quote_ident($dbname) . "." . Modyllic_SQL::quote_ident($name)); while ($data_row = $data_sth->fetch(PDO::FETCH_ASSOC)) { $table->add_row($data_row); } } } }
static function schema(array $load) { Modyllic_Tokenizer::on_advance(array("Modyllic_Status", "status")); try { $schema = Modyllic_Loader::load($load); } catch (Modyllic_Exception $e) { Modyllic_Status::clear_progress(); Modyllic_Status::warn($e->getMessage() . "\n"); if (Modyllic_Status::$debug) { Modyllic_Status::warn($e->getTraceAsString() . "\n"); } exit(1); } catch (Modyllic_Loader_Exception $e) { Modyllic_Status::clear_progress(); Modyllic_Status::warn($e->getMessage() . "\n"); exit(1); } catch (Exception $e) { Modyllic_Status::clear_progress(); throw $e; } Modyllic_Status::clear_progress(); return $schema; }