/** * Begin profile. * * @param $category * @param $token */ public static function beginProfile($category, $token) { Trace::beginProfile($category, $token); }
/** * Returns the number of records. * * @param string $q kept to match {@see \rock\db\common\QueryInterface}, its value is ignored. * @param ConnectionInterface|Connection $connection the Mongo connection used to execute the query. * If this parameter is not given, the `mongodb` application component will be used. * @return integer number of records * @throws MongoException on failure. */ public function count($q = '*', ConnectionInterface $connection = null) { $cursor = $this->buildCursor($connection); $rawQuery = 'find(' . Json::encode($cursor->info()) . ')'; $token = ['query' => $rawQuery, 'valid' => true, 'cache' => false]; //Log::info($token, __METHOD__); Trace::beginProfile('mongodb.query', $token); $cache = $cacheKey = null; $lock = true; if (($result = $this->getCache($rawQuery, $token, null, null, $cache, $cacheKey, $lock)) !== false) { return $result; } if ($lock === false) { return 0; } try { $result = $cursor->count(); $this->setCache($result, $cache, $cacheKey); Trace::endProfile('mongodb.query', $token); Trace::trace('mongodb.query', $token); return $result; } catch (\Exception $e) { $message = $e->getMessage() . "\nThe query being executed was: {$rawQuery}"; Trace::endProfile('mongodb.query', $token); $token['valid'] = false; $token['exception'] = defined('ROCK_DEBUG') && ROCK_DEBUG === true ? $e : $message; Trace::trace('mongodb.query', $token); if (isset($cache, $cacheKey) && $cache instanceof CacheInterface) { $cache->unlock($cacheKey); } throw new MongoException($message, [], 0, $e); } }
/** * Executes Mongo command. * * @param array $command command specification. * @param array $options options in format: "name" => "value" * @return array database response. * @throws MongoException on failure. */ public function executeCommand($command, array $options = []) { $rawQuery = $this->getName() . '.$cmd(' . Json::encode($command) . ', ' . Json::encode($options) . ')'; $token = ['query' => $rawQuery, 'valid' => true, 'cache' => false]; //Log::info($token, __METHOD__); Trace::beginProfile('mongodb.query', $token); try { $result = $this->mongoDb->command($command, $options); $this->tryResultError($result); Trace::endProfile('mongodb.query', $token); Trace::trace('mongodb.query', $token); return $result; } catch (\Exception $e) { $message = $e->getMessage() . "\nThe query being executed was: {$rawQuery}"; Trace::endProfile('mongodb.query', $token); $token['valid'] = false; $token['exception'] = defined('ROCK_DEBUG') && ROCK_DEBUG === true ? $e : $message; Trace::trace('mongodb.query', $token); throw new MongoException($message, [], 0, $e); } }
/** * Establishes a DB connection. * It does nothing if a DB connection has already been established. * * @throws DbException if connection fails */ public function open() { if ($this->pdo !== null) { return; } if (!empty($this->masters)) { $connection = $this->openFromPool($this->masters, $this->masterConfig); if ($connection !== null) { $this->pdo = $connection->pdo; return; } else { throw new DbException('None of the master DB servers is available.'); } } if (empty($this->dsn)) { throw new DbException('Connection::dsn cannot be empty.'); } $token = 'Opening DB connection: ' . $this->dsn; try { Trace::trace('db', $token); Trace::beginProfile('db', $token); $this->pdo = $this->createPdoInstance(); $this->initConnection(); Trace::endProfile('db', $token); } catch (\PDOException $e) { Trace::endProfile('db', $token); throw new DbException($e->getMessage(), [], 0, $e); } }
/** * Deletes the file with given _id. * * @param mixed $id _id of the file to find. * @return boolean whether the operation was successful. * @throws MongoException on failure. */ public function delete($id) { $token = 'Inserting file uploads into ' . $this->getFullName(); //Log::info($token); Trace::beginProfile('mongodb.query', $token); try { $result = $this->mongoCollection->delete($id); $this->tryResultError($result); Trace::endProfile('mongodb.query', $token); Trace::trace('mongodb.query', $token); return true; } catch (\Exception $e) { $message = $e->getMessage() . "\nThe query being executed was: {$token}"; Trace::endProfile('mongodb.query', $token); $token['valid'] = false; $token['exception'] = defined('ROCK_DEBUG') && ROCK_DEBUG === true ? $e : $message; Trace::trace('mongodb.query', $token); throw new MongoException($message, [], $e); } }
/** * Establishes a Mongo connection. * It does nothing if a Mongo connection has already been established. * * @throws MongoException if connection fails */ public function open() { if ($this->mongoClient === null) { if (empty($this->dsn)) { throw new MongoException($this->className() . '::dsn cannot be empty.'); } $token = 'Opening MongoDB connection: ' . $this->dsn; try { Trace::trace('mongodb', $token); Trace::beginProfile('mongodb', $token); $options = $this->options; $options['connect'] = true; if ($this->defaultDatabaseName !== null) { $options['db'] = $this->defaultDatabaseName; } $this->mongoClient = new \MongoClient($this->dsn, $options); $this->initConnection(); Trace::endProfile('mongodb', $token); } catch (\Exception $e) { Trace::endProfile('mongodb', $token); throw new MongoException($e->getMessage(), [], 0, $e); } } }
/** * Performs the actual DB query of a SQL statement. * * @param string $method method of PDOStatement to be called * @param integer $fetchMode the result fetch mode. Please refer to [PHP manual](http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php) * for valid fetch modes. If this parameter is null, the value set in {@see \rock\db\Command::$fetchMode} will be used. * @return mixed the method execution result * @throws DbException if the query causes any problem */ protected function queryInternal($method, $fetchMode = null) { $connection = $this->connection; $rawSql = $this->getRawSql(); $token = ['dsn' => $connection->dsn, 'sql' => $rawSql, 'valid' => true, 'cache' => false]; Trace::beginProfile('db.query', $token); $cache = null; /** @var $cache CacheInterface */ if ($connection->enableQueryCache && $method !== '') { $cache = Instance::ensure($connection->queryCache, null, [], false); } $lock = true; if ($cache instanceof CacheInterface) { $cacheKey = json_encode([__CLASS__, $method, $connection->dsn, $connection->username, $rawSql]); $result = $cache->get($cacheKey); if (is_array($result) && array_key_exists(0, $result)) { Trace::increment('cache.db', 'Cache query DB connection: ' . $connection->dsn); Trace::endProfile('db.query', $token); $token['cache'] = true; Trace::trace('db.query', $token); return $result[0]; } $lock = $cache->lock($cacheKey); } if ($lock === false) { return null; } $this->prepare(true); try { $this->pdoStatement->execute(); if ($method === '') { $result = new DataReader($this); } else { if ($fetchMode === null) { $fetchMode = $this->fetchMode; } $result = call_user_func_array([$this->pdoStatement, $method], (array) $fetchMode); if ($result === false) { $result = null; } $this->pdoStatement->closeCursor(); } if (isset($cache, $cacheKey) && $cache instanceof CacheInterface) { $cache->set($cacheKey, [$result], $connection->queryCacheExpire, $connection->queryCacheTags ?: $this->getRawEntityNames()); $cache->unlock($cacheKey); } Trace::endProfile('db.query', $token); Trace::trace('db.query', $token); return $result; } catch (\Exception $e) { $message = $e->getMessage() . "\nThe SQL being executed was: {$rawSql}"; Trace::endProfile('db.query', $token); $token['valid'] = false; $token['exception'] = defined('ROCK_DEBUG') && ROCK_DEBUG === true ? $e : $message; Trace::trace('db.query', $token); if (isset($cache, $cacheKey) && $cache instanceof CacheInterface) { $cache->unlock($cacheKey); } throw new DbException($message, [], 0, $e); } }
/** * Performs full text search. * * @param string $search string of terms that MongoDB parses and uses to query the text index. * @param array $condition criteria for filtering a results list. * @param array $fields list of fields to be returned in result. * @param array $options additional optional parameters to the mapReduce command. Valid options include: * - limit - the maximum number of documents to include in the response (by default 100). * - language - the language that determines the list of stop words for the search * and the rules for the stemmer and tokenizer. If not specified, the search uses the default * language of the index. * @return array the highest scoring documents, in descending order by score. * @throws MongoException on failure. */ public function fullTextSearch($search, array $condition = [], array $fields = [], array $options = []) { $command = ['search' => $search]; if (!empty($condition)) { $command['filter'] = $this->buildCondition($condition); } if (!empty($fields)) { $command['project'] = $fields; } if (!empty($options)) { $command = array_merge($command, $options); } $rawQuery = $this->composeLogToken('text', $command); $token = ['query' => $rawQuery, 'valid' => true, 'cache' => false]; //Log::info($rawQuery); Trace::beginProfile('mongodb.query', $token); $cache = $cacheKey = null; if (($result = $this->getCache($rawQuery, $token, $cache, $cacheKey)) !== false) { return $result; } try { $command = array_merge(['text' => $this->getName()], $command); $result = $this->mongoCollection->db->command($command); $this->tryResultError($result); $this->setCache($result['results'], $cache, $cacheKey); Trace::endProfile('mongodb.query', $token); Trace::trace('mongodb.query', $token); return $result['results']; } catch (\Exception $e) { $message = $e->getMessage() . "\nThe query being executed was: {$rawQuery}"; Trace::endProfile('mongodb.query', $token); $token['valid'] = false; $token['exception'] = defined('ROCK_DEBUG') && ROCK_DEBUG === true ? $e : $message; Trace::trace('mongodb.query', $token); throw new MongoException($message, [], 0, $e); } }