function normalize($date) { assert('! is_object($date) or $date instanceOf Modyllic_Token'); $is_object = is_object($date); if ($is_object) { $value = $date->value(); $unquoted = $date->unquote(); } else { $value = $unquoted = $date; } if ($date instanceof Modyllic_Token_Reserved or !$is_object and Modyllic_SQL::is_reserved($value)) { return $value; } if (is_numeric($value) and $value == 0) { return "'0000-00-00 00:00:00'"; } if ($is_object and !$date instanceof Modyllic_Token_String) { throw new Exception("Invalid date value: {$date}"); } if (preg_match('/^(\\d{1,4})-(\\d\\d?)-(\\d\\d?)(?: (\\d\\d?)(?::(\\d\\d?)(?::(\\d\\d?))?)?)?$/', $unquoted, $matches)) { $year = $matches[1]; $mon = $matches[2]; $day = $matches[3]; $hour = isset($matches[4]) ? $matches[4] : 0; $min = isset($matches[5]) ? $matches[5] : 0; $sec = isset($matches[6]) ? $matches[6] : 0; #list( $full, $year, $mon, $day, $hour, $min, $sec ) = $matches; return sprintf("'%04d-%02d-%02d %02d:%02d:%02d'", $year, $mon, $day, $hour, $min, $sec); } else { throw new Exception("Invalid date value: {$date}"); } }
function to_sql() { $sql = ""; if ($dir != "IN") { $sql .= "{$dir} "; } $sql .= Modyllic_SQL::quote_ident($name) . " "; $sql .= $type->to_sql(); return $sql; }
function normalize($year) { $is_object = is_object($year); $value = $is_object ? $year->value() : $year; $unquoted = $is_object ? $year->unquote() : $year; if ($year instanceof Modyllic_Token_Reserved or !$is_object and Modyllic_SQL::is_reserved($value)) { return $value; } if ($year instanceof Modyllic_Token_Num or !$is_object and is_numeric($year)) { $plain = $value + 0; if ($plain == 0) { return "'0000'"; } else { if ($plain > 0 and $plain < 70) { return "'20{$plain}'"; } else { if ($plain >= 70 and $plain < 100) { return "'19{$plain}'"; } else { if ($plain > 1900 and $plain < 2155) { return "'{$plain}'"; } } } } } else { if (!$is_object or $year instanceof Modyllic_Token_String) { $plain = $unquoted + 0; if ($plain >= 0 and $plain < 70) { return "'20{$plain}'"; } else { if ($plain >= 70 and $plain < 100) { return "'19{$plain}'"; } } } } throw new Exception("Expected a valid year, got: {$year}"); }
function normalize($str) { if ($str instanceof Modyllic_Token_Reserved) { return $str->value(); } else { if ($str instanceof Modyllic_Token_String) { $value = $str->unquote(); } else { if ($str instanceof Modyllic_Token_Num) { $value = $str->value(); } else { if (!is_object($str)) { $value = $str; } else { throw new Exception("Expected a valid string, got: {$str}"); } } } } if (isset($this->length)) { $value = substr($value, 0, $this->length); } return Modyllic_SQL::quote_str($value); }
function begin_sql_func($name) { $this->add(Modyllic_SQL::quote_ident($name) . '('); return $this; }
/** * Our string parser, this expects strings to look like <CHR>stuff<CHR> * where <CHR> is a quote character. <CHR> can be escaped by either * doubling it or by preceding it with a backslash. Any character * proceeded by a backslash will be included literally. * For example, the string: foo's test * Could be: 'foo''s test' * Or: 'foo\'s test' * If the quote character is ` then it will return a quoted ident * token rather then a string token. */ private function next_string() { $quote = $this->cmdstr[$this->pos]; $this->pos++; $str = $quote; while ($this->pos < $this->len) { $chr = $this->cmdstr[$this->pos++]; if ($chr == '\\') { $str .= $chr . $this->cmdstr[$this->pos++]; } else { if ($chr == $quote and $this->pos < $this->len and $this->cmdstr[$this->pos] == $quote) { $str .= $chr . $this->cmdstr[$this->pos++]; } else { if ($chr == $quote) { $str .= $chr; break; } else { $str .= $chr; } } } } if ($quote == '`') { return new Modyllic_Token_Ident_Quoted($this->pos, $str); } else { $token = new Modyllic_Token_String($this->pos, $str); // If we're followed by whitespace and a string, then concatenate the string if ($this->peek_next(true) instanceof Modyllic_Token_Whitespace) { $ws = $this->next(true); if ($this->peek_next(true) instanceof Modyllic_Token_String) { $token = new Modyllic_Token_String($this->pos, Modyllic_SQL::quote_str($token->unquote() . $this->next(false)->unquote())); } else { $this->inject($ws); } } return $token; } }
protected function _format_replace($matches) { switch ($matches[1]) { case 'id': $result = Modyllic_SQL::quote_ident(array_shift($this->_format_args)); break; case 'str': $result = Modyllic_SQL::quote_str(array_shift($this->_format_args)); break; case 'lit': $result = array_shift($this->_format_args); break; default: $result = '%' . $matches[1]; } return $result; return $this; }
/** * @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); } } } }