/** * Returns an array of the strings in the selected page * * @param string $pageID * @param string $langID * @return array */ function &getPage($pageID = null, $langID = null) { $langID = $this->_getLangID($langID); $lang_col = $this->_getLangCol($langID); $table = $this->_getLangTable($langID); $query = sprintf('SELECT %s, %s FROM %s WHERE %s ', $this->options['string_id_col'], $lang_col, $table, $this->options['string_page_id_col']); if (is_null($pageID)) { $query .= 'IS NULL'; } else { $query .= ' = ' . $this->db->getTextValue($pageID); } ++$this->_queries; $res = $this->db->query($query); if (PEAR::isError($res)) { return $res; } $strings = array(); while (list($key, $value) = $this->db->fetchInto($res)) { $strings[$key] = $value; } $this->db->freeResult($res); return $strings; }
/** * Frees the resources allocated for this result set * * @return bool true on success. A DB_Error object on failure. */ function free() { $err = $this->dbh->freeResult($this->result); if (DB::isError($err)) { return $err; } $this->result = false; $this->statement = false; return true; }
/** * get the stucture of a field into an array * * @param object $db database object that is extended by this class * @param string $table name of table that should be used in method * @param string $field_name name of field that should be used in method * @return mixed data array on success, a MDB error on failure * @access public */ function getTableFieldDefinition(&$db, $table, $field_name) { $result = $db->query("SELECT \n attnum,attname,typname,attlen,attnotnull,\n atttypmod,usename,usesysid,pg_class.oid,relpages,\n reltuples,relhaspkey,relhasrules,relacl,adsrc\n FROM pg_class,pg_user,pg_type,\n pg_attribute left outer join pg_attrdef on\n pg_attribute.attrelid=pg_attrdef.adrelid \n WHERE (pg_class.relname='{$table}') \n and (pg_class.oid=pg_attribute.attrelid) \n and (pg_class.relowner=pg_user.usesysid) \n and (pg_attribute.atttypid=pg_type.oid)\n and attnum > 0\n and attname = '{$field_name}'\n ORDER BY attnum\n "); if (MDB::isError($result)) { return $result; } $columns = $db->fetchInto($result, MDB_FETCHMODE_ASSOC); $field_column = $columns['attname']; $type_column = $columns['typname']; $db_type = preg_replace('/\\d/', '', strtolower($type_column)); $length = $columns['attlen']; if ($length == -1) { $length = $columns['atttypmod'] - 4; } //$decimal = strtok('(), '); = eh? $type = array(); switch ($db_type) { case 'int': $type[0] = 'integer'; if ($length == '1') { $type[1] = 'boolean'; } break; case 'text': case 'char': case 'varchar': case 'bpchar': $type[0] = 'text'; if ($length == '1') { $type[1] = 'boolean'; } elseif (strstr($db_type, 'text')) { $type[1] = 'clob'; } break; /* case 'enum': preg_match_all('/\'.+\'/U',$row[$type_column], $matches); $length = 0; if(is_array($matches)) { foreach($matches[0] as $value) { $length = max($length, strlen($value)-2); } } unset($decimal); case 'set': $type[0] = 'text'; $type[1] = 'integer'; break; */ /* case 'enum': preg_match_all('/\'.+\'/U',$row[$type_column], $matches); $length = 0; if(is_array($matches)) { foreach($matches[0] as $value) { $length = max($length, strlen($value)-2); } } unset($decimal); case 'set': $type[0] = 'text'; $type[1] = 'integer'; break; */ case 'date': $type[0] = 'date'; break; case 'datetime': case 'timestamp': $type[0] = 'timestamp'; break; case 'time': $type[0] = 'time'; break; case 'float': case 'double': case 'real': $type[0] = 'float'; break; case 'decimal': case 'money': case 'numeric': $type[0] = 'decimal'; break; case 'oid': case 'tinyblob': case 'mediumblob': case 'longblob': case 'blob': $type[0] = 'blob'; $type[1] = 'text'; break; case 'year': $type[0] = 'integer'; $type[1] = 'date'; break; default: return $db->raiseError(MDB_ERROR_MANAGER, NULL, NULL, 'List table fields: unknown database attribute type'); } if ($columns['attnotnull'] == 'f') { $notnull = 1; } if (!preg_match("/nextval\\('([^']+)'/", $columns['adsrc'])) { $default = substr($columns['adsrc'], 1, -1); } $definition = array(); for ($field_choices = array(), $datatype = 0; $datatype < count($type); $datatype++) { $field_choices[$datatype] = array('type' => $type[$datatype]); if (isset($notnull)) { $field_choices[$datatype]['notnull'] = 1; } if (isset($default)) { $field_choices[$datatype]['default'] = $default; } if ($type[$datatype] != 'boolean' && $type[$datatype] != 'time' && $type[$datatype] != 'date' && $type[$datatype] != 'timestamp') { if (strlen($length)) { $field_choices[$datatype]['length'] = $length; } } } $definition[0] = $field_choices; if (preg_match("/nextval\\('([^']+)'/", $columns['adsrc'], $nextvals)) { $implicit_sequence = array(); $implicit_sequence['on'] = array(); $implicit_sequence['on']['table'] = $table; $implicit_sequence['on']['field'] = $field_name; $definition[1]['name'] = $nextvals[1]; $definition[1]['definition'] = $implicit_sequence; } // check that its not just a unique field if (MDB::isError($indexes = $db->queryAll("SELECT \n oid,indexrelid,indrelid,indkey,indisunique,indisprimary \n FROm pg_index, pg_class \n WHERE (pg_class.relname='{$table}') \n AND (pg_class.oid=pg_index.indrelid)", NULL, MDB_FETCHMODE_ASSOC))) { return $indexes; } $indkeys = explode(' ', $indexes['indkey']); if (in_array($columns['attnum'], $indkeys)) { if (MDB::isError($indexname = $db->queryAll("SELECT \n relname FROM pg_class WHERE oid={$columns['indexrelid']}"))) { return $indexname; } $is_primary = $indexes['isdisprimary'] == 't'; $is_unique = $indexes['isdisunique'] == 't'; $implicit_index = array(); $implicit_index['unique'] = 1; $implicit_index['FIELDS'][$field_name] = $indexname['relname']; $definition[2]['name'] = $field_name; $definition[2]['definition'] = $implicit_index; } $db->freeResult($result); return $definition; }
/** * Process Query Results * * @access private * @param object Mediawiki Result Object * @return array Array of Article objects. */ private function processQueryResults($result) { /*******************************/ /* Random Count Pick Generator */ /*******************************/ $randomCount = $this->parameters->getParameter('randomcount'); if ($randomCount > 0) { $nResults = $this->DB->numRows($result); //mt_srand() seeding was removed due to PHP 5.2.1 and above no longer generating the same sequence for the same seed. //Constrain the total amount of random results to not be greater than the total results. if ($randomCount > $nResults) { $randomCount = $nResults; } //This is 50% to 150% faster than the old while (true) version that could keep rechecking the same random key over and over again. //Generate pick numbers for results. $pick = range(1, $nResults); //Shuffle the pick numbers. shuffle($pick); //Select pick numbers from the beginning to the maximum of $randomCount. $pick = array_slice($pick, 0, $randomCount); } $articles = []; /**********************/ /* Article Processing */ /**********************/ $i = 0; while ($row = $result->fetchRow()) { $i++; //In random mode skip articles which were not chosen. if ($randomCount > 0 && !in_array($i, $pick)) { continue; } if ($this->parameters->getParameter('goal') == 'categories') { $pageNamespace = NS_CATEGORY; $pageTitle = $row['cl_to']; } elseif ($this->parameters->getParameter('openreferences')) { if (count($this->parameters->getParameter('imagecontainer')) > 0) { $pageNamespace = NS_FILE; $pageTitle = $row['il_to']; } else { //Maybe non-existing title $pageNamespace = $row['pl_namespace']; $pageTitle = $row['pl_title']; } } else { //Existing PAGE TITLE $pageNamespace = $row['page_namespace']; $pageTitle = $row['page_title']; } // if subpages are to be excluded: skip them if (!$this->parameters->getParameter('includesubpages') && strpos($pageTitle, '/') !== false) { continue; } $title = \Title::makeTitle($pageNamespace, $pageTitle); $thisTitle = $this->parser->getTitle(); //Block recursion from happening by seeing if this result row is the page the DPL query was ran from. if ($this->parameters->getParameter('skipthispage') && $thisTitle->equals($title)) { continue; } $articles[] = Article::newFromRow($row, $this->parameters, $title, $pageNamespace, $pageTitle); } $this->DB->freeResult($result); return $articles; }
/** * get the stucture of an index into an array * * @param object $db database object that is extended by this class * @param string $table name of table that should be used in method * @param string $index_name name of index that should be used in method * @return mixed data array on success, a MDB error on failure * @access public */ function getTableIndexDefinition(&$db, $table, $index_name) { if ($index_name == 'PRIMARY') { return $db->raiseError(MDB_ERROR_MANAGER, NULL, NULL, 'Get table index definition: PRIMARY is an hidden index'); } if (MDB::isError($result = $db->query("SHOW INDEX FROM {$table}"))) { return $result; } $definition = array(); while (is_array($row = $db->fetchInto($result, MDB_FETCHMODE_ASSOC))) { if ($db->options['optimize'] != 'portability') { $row = array_change_key_case($row); } $key_name = $row['key_name']; if (!strcmp($index_name, $key_name)) { if (!$row['non_unique']) { $definition[$index_name]['unique'] = 1; } $column_name = $row['column_name']; $definition['FIELDS'][$column_name] = array(); if (isset($row['collation'])) { $definition['FIELDS'][$column_name]['sorting'] = $row['collation'] == 'A' ? 'ascending' : 'descending'; } } } $db->freeResult($result); if (!isset($definition['FIELDS'])) { return $db->raiseError(MDB_ERROR_MANAGER, NULL, NULL, 'Get table index definition: it was not specified an existing table index'); } return $definition; }
/** * list all fields in a tables in the current database * * @param object $db database object that is extended by this class * @param string $table name of table that should be used in method * @return mixed data array on success, a MDB error on failure * @access public */ function listTableFields(&$db, $table) { $result = $db->query("SELECT * FROM {$table}"); if (MDB::isError($result)) { return $result; } $columns = $db->getColumnNames($result); if (MDB::isError($columns)) { $db->freeResult($columns); return $columns; } return array_flip($columns); }
/** * Start a query build. * * @access public * @param boolean Calculate Found Rows * @return mixed Mediawiki Result Object or False */ public function buildAndSelect($calcRows = false) { global $wgNonincludableNamespaces; wfProfileIn(__METHOD__ . ": Query Build"); $options = []; $parameters = $this->parameters->getAllParameters(); foreach ($parameters as $parameter => $option) { $function = "_" . $parameter; //Some parameters do not modifiy the query so we check if the function to modify the query exists first. $success = true; if (method_exists($this, $function)) { $success = $this->{$function}($option); } if ($success === false) { throw new \MWException(__METHOD__ . ": SQL Build Error returned from {$function} for " . serialize($option) . "."); return; } $this->parametersProcessed[$parameter] = true; } if (!$this->parameters->getParameter('openreferences')) { //Add things that are always part of the query. $this->addTable('page', $this->tableNames['page']); $this->addSelect(['page_namespace' => $this->tableNames['page'] . '.page_namespace', 'page_id' => $this->tableNames['page'] . '.page_id', 'page_title' => $this->tableNames['page'] . '.page_title']); } //Always add nonincludeable namespaces. if (is_array($wgNonincludableNamespaces) && count($wgNonincludableNamespaces)) { $this->addNotWhere([$this->tableNames['page'] . '.page_namespace' => $wgNonincludableNamespaces]); } if ($this->offset !== false) { $options['OFFSET'] = $this->offset; } if ($this->limit !== false) { $options['LIMIT'] = $this->limit; } elseif ($this->offset !== false && $this->limit === false) { $options['LIMIT'] = $this->parameters->getData('count')['default']; } if ($this->parameters->getParameter('openreferences')) { if (count($this->parameters->getParameter('imagecontainer')) > 0) { //$sSqlSelectFrom = $sSqlCl_to.'ic.il_to, '.$sSqlSelPage."ic.il_to AS sortkey".' FROM '.$this->tableNames['imagelinks'].' AS ic'; $tables = ['ic' => 'imagelinks']; } else { //$sSqlSelectFrom = "SELECT $sSqlCalcFoundRows $sSqlDistinct ".$sSqlCl_to.'pl_namespace, pl_title'.$sSqlSelPage.$sSqlSortkey.' FROM '.$this->tableNames['pagelinks']; $this->addSelect(['pl_namespace', 'pl_title']); $tables = ['pagelinks']; } } else { $tables = $this->tables; if (count($this->groupBy)) { $options['GROUP BY'] = $this->groupBy; } if (count($this->orderBy)) { $options['ORDER BY'] = $this->orderBy; $_lastOrder = array_pop($options['ORDER BY']); $_lastOrder .= " " . $this->direction; $options['ORDER BY'][] = $_lastOrder; } } if ($this->parameters->getParameter('goal') == 'categories') { $categoriesGoal = true; $select = [$this->tableNames['page'] . '.page_id']; $options[] = 'DISTINCT'; } else { if ($calcRows) { $options[] = 'SQL_CALC_FOUND_ROWS'; } if ($this->distinct) { $options[] = 'DISTINCT'; } $categoriesGoal = false; $select = $this->select; } wfProfileOut(__METHOD__ . ": Query Build"); wfProfileIn(__METHOD__ . ": Database Query"); $queryError = false; try { if ($categoriesGoal) { $result = $this->DB->select($tables, $select, $this->where, __METHOD__, $options, $this->join); while ($row = $result->fetchRow()) { $pageIds[] = $row['page_id']; } $sql = $this->DB->selectSQLText(['clgoal' => 'categorylinks'], ['clgoal.cl_to'], ['clgoal.cl_from' => $pageIds], __METHOD__, ['ORDER BY' => 'clgoal.cl_to ' . $this->direction]); } else { $sql = $this->DB->selectSQLText($tables, $select, $this->where, __METHOD__, $options, $this->join); } $result = $this->DB->query($sql); if ($calcRows) { $calcRowsResult = $this->DB->query('SELECT FOUND_ROWS() AS rowcount'); $total = $this->DB->fetchRow($calcRowsResult); $this->foundRows = intval($total['rowcount']); $this->DB->freeResult($calcRowsResult); } } catch (Exception $e) { $queryError = true; } if ($queryError == true || $result === false) { throw new \MWException(__METHOD__ . ": " . wfMessage('dpl_query_error', DPL_VERSION, $this->DB->lastError())->text()); } wfProfileOut(__METHOD__ . ": Database Query"); return $result; }
/** * list all fields in a tables in the current database * * @param object $db database object that is extended by this class * @param string $table name of table that should be used in method * @return mixed data array on success, a MDB error on failure * @access public */ function listTableFields(&$db, $table) { $result = $db->query("SELECT RDB{$FIELD_SOURCE} FROM RDB{$RELATION_FIELDS} WHERE RDB{$RELATION_NAME}='{$table}'"); if (MDB::isError($result)) { return $result; } $columns = $db->getColumnNames($result); if (MDB::isError($columns)) { $db->freeResult($columns); } return $columns; }