function testTranslate() { //echo $this->DB->translate_query('select PubType, BiblioString from Publications', 'fr'); //exit; $sql = 'select PubType, BiblioString from Publications limit 5'; $start = microtime_float(); $res = $this->DB->query($sql, $this->db) or die(xf_db_error($this->db)); while ($row = xf_db_fetch_assoc($res)) { print_r($row); } $stop1 = microtime_float() - $start; $start = microtime_float(); $res3 = $this->DB->query($sql, $this->db) or die(xf_db_error($this->db)); while ($row = xf_db_fetch_assoc($res3)) { print_r($row); } $stop3 = microtime_float() - $start; $start = microtime_float(); $res2 = xf_db_query($sql, $this->db) or die(xf_db_error($this->db)); while ($row = xf_db_fetch_assoc($res2)) { print_r($row); } $stop2 = microtime_float() - $start; echo "MySQL: {$stop2} ; Translated: {$stop1} ; Second translated: {$stop3}"; $parser = new SQL_Parser(null, 'MySQL'); //$sql = 'select IFNULL(f.PubType,d.PubType) as PubType, IFNULL(f.BiblioString,d.BiblioString) as BiblioString from Publications d left join Publications_fr f on d.PubID=f.PubID'; $data = $parser->parse($sql); //print_r($data); $compiler = new SQL_Compiler(); echo $compiler->compile($data); }
/** * Returns an SQL query that will obtain the domain of this relationship. The Domain * is slightly different than the actual relationship, in that it returns all eligible * rows that can be added to the relationship (and rows already in the relationship). */ function getDomainSQL() { $relationship =& $this->_schema; // obtain reference to the relationship in question // The 'domain_sql' attribute of a relationship defines the SQL select statement that // is used to obtain the set of candidates for a relationship. This can be specified // in the ini file using the __domain__ attribute of a relationship, or it can be parsed // from the existiing 'sql' attribute. if (!isset($relationship['domain_sql'])) { import('SQL/Compiler.php'); // compiles SQL tree structure into query strings import('SQL/Parser/wrapper.php'); // utility methods for dealing with SQL structures $compiler = new SQL_Compiler(); // the compiler we will use to generate the eventual SQL $parsed_sql = unserialize(serialize($relationship['parsed_sql'])); // we make a deep copy of the existing 'parsed_sql' structure that was // created in the "readRelationshipsIniFile" method. We deep copy, because // some of the methods in SQL_Parser_wrapper work directly on the // datastructure - but we want to leave it unchanged. $wrapper = new SQL_Parser_wrapper($parsed_sql); // create a new wrapper to operate on the sql data structure. $wrapper->removeWhereClausesWithTable($this->_sourceTable->tablename); $wrapper->removeJoinClausesWithTable($this->_sourceTable->tablename); // We remove all Where and Join clauses that use columns from the current table. // This is because portions of the sql pertaining to the current table // likely represent specifications within the domain to mark that an // element of the domain is related to the current table. $wrapper->removeWhereClausesWithPattern('/\\$\\w+/'); $wrapper->removeJoinClausesWithPattern('/\\$\\w+/'); // Similarly we need to remove any clauses containing variables which // get filled in by the current table. The rationale is the same as // for removing clauses pertaining to the current table. $fkVals = $this->getForeignKeyValues(); // We obtain the foreign key values for this relationship because they // will help us to decide which columns in the remaining query are // helpful for obtaining the domain. $uselessTables = array(); // will hold list of tables that we don't need $fkTables = array_keys($fkVals); // list of tables that are involved in foreign key relationships in this // relationship. foreach ($fkVals as $fkTable => $fkFields) { $foundVal = 0; $foundLink = 0; // keep track of which tables actually have real values assigned. foreach ($fkFields as $fieldVal) { //if ( !preg_match('/^__(\w+)_auto_increment__$/', $fieldVal) ){ // // A field with a value of the form __Tablename__auto_increment__ is a placeholder // // for an auto generated id. If the only values specified for a table are placeholders // // then that table is pretty much useless as a domain query... it can be eliminated. // $foundVal++; // // //} if (is_scalar($fieldVal) and strpos($fieldVal, '$') === 0) { // This table is linked directly to the current table... hence it is only a join // table. $foundLink++; } } if ($foundLink) { // no real valus found.. mark table as useless. $uselessTables[] = $fkTable; } } foreach ($uselessTables as $table_name) { // Remove all useless tables from the query's where and join clauses. $wrapper->removeWhereClausesWithTable($table_name); $wrapper->removeJoinClausesWithTable($table_name); $wrapper->removeColumnsFromTable($table_name); } $domain_tables = array_diff($relationship['selected_tables'], $uselessTables); if (!$domain_tables) { $domain_tables = $relationship['selected_tables']; } $table_ranks = array(); foreach ($this->_schema['columns'] as $col) { list($tname) = explode('.', $col); if (!isset($table_ranks[$tname])) { $table_ranks[$tname] = 0; } $table_ranks[$tname]++; } $high = null; $high_score = 0; foreach ($domain_tables as $dt) { if ($table_ranks[$dt] > $high_score) { $high = $dt; $high_score = $table_ranks[$dt]; } } $domain_tables = array($high); if (count($domain_tables) !== 1) { return PEAR::raiseError("Error calculating domain tables for relationship '" . $this->_name . "'. Selected tables are {" . implode(',', $relationship['selected_tables']) . "} and Useless tables are {" . implode(',', $uselessTables) . "}.", null, null, null, 1); } $relationship['domain_table'] = array_pop($domain_tables); $wrapper->packTables(); // Previous steps have only eliminated useless tables with respect to query // parameters. There may still be some tables listed in the query that don't // offer anything. Notice that we pass the list of selected tables to this // method to indicate that tables whose columns are selected need to be there // and should be left intact. $relationship['domain_sql'] = $compiler->compile($parsed_sql); } return $relationship['domain_sql']; }
function test_misc() { $parser = new SQL_Parser(null, 'MySQL'); $compiler = new SQL_Compiler(); print_r($parser->parse("select foo.a from foo")); print_r($parser->parse("select a, b, c from foo")); print_r($parser->parse("SELECT F.a as column1, B.b as column2 FROM Foo F inner join Bar B on F.c=B.c where column1 = 'val1' and column2 = 'val2'")); $res = $parser->parse("SELECT f.a from Foo f where conv('a',16,2) = '2005'"); if (PEAR::isError($res)) { echo $res->toString() . Dataface_Error::printStackTrace(); } else { print_r($res); } $res = $parser->parse("SELECT * from Publications where Expires > NOW()"); if (PEAR::isError($res)) { echo $res->toString() . Dataface_Error::printStackTrace(); } else { print_r($res); echo $compiler->compile($res); } }