/** * executes query * * @param string $sql * @return result */ public function query($sql) { $sqlDebug = defined("DEBUG") && DEBUG && isset($_REQUEST["sql_debug"]); $sql = $sql; if ($sqlDebug) { $stats = new Stats(); } $this->querycount++; $res = mysql_query($sql, $this->connection) or $this->error(mysql_error(), $sql); if ($sqlDebug) { $stats->storeDifference(); echo "\n<!--\n"; echo "Query #{$this->querycount}: {$sql}\n"; echo "Memory used: {$stats->memUsedFmted} bytes\n"; echo "Time spent: {$stats->timeSpent} seconds\n"; echo "-->\n"; } return $res; }
/** * Loads a lot of objects at a time. Used to avoid multiple loadById calls. This saves lots of queries when using functions such as lister. * * @param array $ids array of ids to load * @param string $table the table from which to load the objects (ie the name of the class) * @param string $field which field to use for matching the data in the ids array (most likely the id field) * @param string $order used if any sorting is needed (added to the sql query) * @uses TABLEPREFIX to get the correct table name (prefix + supplied table name) * @uses DB::getBufferObjects load buffered objects (makes sure that an object doesn't need to be loaded twice on the same pageload, this saves queries) * @uses Mem::get check if the object is already in the memcache (if it is, we don't need to load it from the database) * @uses DB::query runs the select query from the database and return the matching rows * @uses function __getObj gets the needed data and creates the object * @uses DB::setBufferObjects adds the loaded object to the buffer to avoid loading it again in the future * @uses Misc::arrayKeyMerge() to merge the objects loaded by buffer or memcache with those loaded from database * @return array an array of objects */ protected static function loadByIds($IDs, $objName, $field = "id", $orderBy = null) { global $db; $loadDebug = defined("DEBUG") && DEBUG && isset($_GET["load_debug"]); $bufferObjects = $db->getBufferObjects(); $result = array(); if ($loadDebug) { $stats = new Stats(); $stats->numIDs = count($IDs); $stats->sql = "<none generated>"; } // Check local memory storage ("buffer") for the IDs requested. foreach ($IDs as $idx => $objID) { if (isset($bufferObjects[$objName][$objID])) { $result[$objID] = $bufferObjects[$objName][$objID]; unset($IDs[$idx]); } } if ($loadDebug) { $stats->numIDsFromCache = count($result); } // Fetch any remaining objects from the database. if ($IDs) { // Ascertain that the IDs are integers. $intIDs = array(); foreach ($IDs as $objID) { $intIDs[] = (int) $objID; } // Construct SQL $sql = sprintf("select * from %s where %s in (%s)", self::TABLEPREFIX . strtolower($objName), $field, implode(",", $intIDs)); if ($orderBy) { $sql .= " order by {$orderBy}"; } if ($loadDebug) { $stats->sql = $sql; } // Fetch objects and store in local memory ("buffer"). $res = $db->query($sql); while ($row = mysql_fetch_assoc($res)) { $objID = (int) $row["id"]; $obj = self::__getObj($objName, $row); $db->setBufferObjects($obj, $objName); $result[$objID] = $obj; } } // Wouldn't this be awesome? It would. But we can't, because a lot of // the code relies on being able to pass in any number of IDs and only // get existing objects back. <profanities /> /* $missingIDs = array_diff(array_keys($result), $IDs); if ($missingIDs) { throw new ObjectsNotFoundException(implode(", ", $missingIDs)); } */ if ($loadDebug) { $stats->storeDifference(); echo "\n<!--\n"; echo "Load {$stats->numIDs} {$objName} objects\n"; echo "{$stats->numIDsFromCache} objects in cache.\n"; echo "SQL: {$stats->sql}\n"; echo $stats->numIDs - count($result) . " missing objects.\n"; echo "Memory used: {$stats->memUsedFmted} bytes\n"; echo "Time spent: {$stats->timeSpent} seconds\n"; echo "-->\n"; } return $result; }