public function evaluateQuery(Query $query)
 {
     $select = $this->evaluateSelect($query->getSelect()) . " ";
     $from = $this->evaluateFrom($query->getFrom()) . " ";
     $where = $this->evaluateWhere($query->getWhere()) . " ";
     $order = $this->evaluateOrder($query->getOrder()) . " ";
     $groupBy = $this->evaluateGroupBy($query->getGroupBy()) . " ";
     $limit = '';
     if ($query->hasLimit()) {
         $limit = 'LIMIT ' . $query->getLimitMax() . ' ' . $query->getLimitOffset() . ' ';
         // http://www.postgresql.org/docs/8.1/static/queries-limit.html
     }
     return $select . $from . $where . $order . $limit . $groupBy;
 }
 public function evaluateQuery(Query $query)
 {
     $select = $this->evaluateSelect($query->getSelect()) . ' ';
     $from = '';
     $order = $this->evaluateOrder($query->getOrder()) . ' ';
     $groupBy = $this->evaluateGroupBy($query->getGroupBy()) . ' ';
     // SQLServer 2008 no tiene LIMIT, hay que hacerlo con una subquery usando ROWNUM
     // Soluciona problema de paginacion en SQLServer, como esta en DAL::listAll()
     //
     if ($query->hasLimit()) {
         // FIXME:
         // El filtro del where que no es el filtro por rowNum
         // debe hacerse en la consulta interna, sino se toman
         // rowNums en la consulta interna que luego no estan
         // en la consulta final, eso afecta al resultado paginado,
         // porque se pagina por rowNum de rows que no matchean el where, ej:
         //  - consulta interna devuelve 1,2,3,4,5,6,7,8
         //  - consulta externa tiene max=3, offset=0
         //  - where matchea solo 2,4,5,7
         //  - el resultado es solo 2, en lugar de 2,4,5 (son los primeros 3 que matchean)
         //
         // problema, el where incluye condiciones que no son sobre la tabla utilizada
         // en la consulta interna, esto afecta?
         $tableName = $query->getLimitTable();
         $offset = $query->getLimitOffset();
         $max = $query->getLimitMax();
         // La consulta interna es para hacer paginacion
         // WHERE: Las condiciones donde dice tableName pone T2 (no puede evaluar condiciones sobre atributos de tablas no mencionados en el FROM)
         //  - http://social.msdn.microsoft.com/Forums/sqlserver/en-US/3b2e0875-e98c-4931-bcb4-e9f449b637d7/the-multipart-identifier-aliasfield-could-not-be-bound
         // Hago el evaluate del from aca porque tengo que cambiar el FROM de tableName por la subconsulta necesaria para el limit
         $queryFrom = $query->getFrom();
         $alias;
         if (count($queryFrom) == 0) {
             // ERROR! es obligatorio por lo menos una!
             throw new Exception("FROM no puede ser vacio");
         } else {
             /*
             $res = "FROM ";
             foreach ($queryFrom as $table)
             {
                if ( $table->name == $tableName )
                {
                   $alias = $table->alias;
                   
                   $res .= '( SELECT ROW_NUMBER() OVER (ORDER BY id) AS rowNum, * '.
                           'FROM '. $tableName .
                           $this->evaluateWhere( $query->getWhere() ) .
                           ' ) '. $alias .', ';
                }
                else
                {
                   $res .= $table->name .' '. $table->alias .', ';
                }
             }
             $from = substr($res, 0, -2) .' ';
             */
             $alias = 'subq';
             // * selecciona multiples columnas con mismo nombre en distintas tablas
             $subquery = '( ' . $select . ', ROW_NUMBER() OVER (ORDER BY ' . $tableName . '.id) AS rowNum ' . $this->evaluateFrom($query->getFrom()) . ' ' . $this->evaluateWhere($query->getWhere()) . ' ' . $order . $groupBy . ' ) ' . $alias . ' ';
             $from = 'FROM ' . $subquery;
             $select = 'SELECT * ';
             // Select para la query ppal. agregaciones y group se harian en la subquery
         }
         $where = 'WHERE ' . $alias . '.rowNum-1 >= ' . $offset . ' AND ' . $alias . '.rowNum-1 < ' . ($offset + $max);
         return $select . $from . $where;
     }
     // hasLimit
     // !hasLimit
     $from = $this->evaluateFrom($query->getFrom()) . ' ';
     $where = $this->evaluateWhere($query->getWhere()) . ' ';
     return $select . $from . $where . $order . $groupBy;
 }
 public function evaluateQuery(Query $query)
 {
     $select = $this->evaluateSelect($query->getSelect()) . ' ';
     $from = $this->evaluateFrom($query->getFrom()) . ' ';
     $where = $this->evaluateWhere($query->getWhere()) . ' ';
     $order = $this->evaluateOrder($query->getOrder()) . ' ';
     $groupBy = $this->evaluateGroupBy($query->getGroupBy()) . ' ';
     $limit = '';
     if ($query->hasLimit()) {
         $limit = 'LIMIT ' . $query->getLimitOffset() . ', ' . $query->getLimitMax() . ' ';
         // http://www.sqlite.org/lang_select.html
     }
     return $select . $from . $where . $order . $limit . $groupBy;
 }
Example #4
0
 /**
  * @param Query $query
  * @return mixed
  */
 public function query(Query $query)
 {
     $time = microtime(TRUE);
     $packageName = $query->getPackage();
     $counterName = $query->getCounter();
     $from = $query->getFrom();
     $to = $query->getTo();
     $count = $query->getCount();
     $action = $query->getAction();
     $token = $query->getToken();
     $value = $query->getValue();
     $tokenCreated = FALSE;
     $result = NULL;
     $databaseFilename = $this->getDatabaseFileName($packageName);
     if (!file_exists($databaseFilename) && $action !== Query::ACTION_SAVE) {
         throw new NotFoundException(sprintf('Package %s has no counters. Save a value to initialize!', $packageName));
     }
     switch ($action) {
         case Query::ACTION_COMPARE:
             $history = (array) $this->getByCount($packageName, $counterName, 2048);
             $lastValue = $this->getLastValue($packageName, $counterName);
             $result = array(array('value' => $lastValue, 'time' => $this->getLastTimestamp($packageName, $counterName), 'deviation' => $this->getCalculator()->deviation($history, $lastValue)), array('value' => $value, 'time' => time(), 'deviation' => $this->getCalculator()->deviation($history, $value)));
             break;
         case Query::ACTION_POLL:
         case Query::ACTION_GET:
             $this->validatePackageToken($packageName, $token);
             if ($from && $count) {
                 $result = $this->getByRange($packageName, $counterName, $from, $to, $count);
             } elseif ($from) {
                 $result = $this->getByRange($packageName, $counterName, $from, $to);
             } elseif ($count) {
                 $result = $this->getByCount($packageName, $counterName, $count);
             } else {
                 $result = $this->getLastValue($packageName, $counterName);
             }
             break;
         case Query::ACTION_COUNTERS:
             $this->validatePackageToken($packageName, $token);
             $result = $this->getCountersFromPackage($packageName);
             break;
         case Query::ACTION_SAVE:
             if (!file_exists($databaseFilename)) {
                 $token = $this->createTokenForPackage($packageName, $token);
                 $tokenCreated = TRUE;
             } else {
                 $this->validatePackageToken($packageName, $token);
             }
             $result = $this->saveValue($packageName, $counterName, $value);
             break;
         default:
             throw new NumerologException(sprintf('Invalid Numerolog action: %s', $action));
     }
     $response = array('values' => $result);
     if (1 < count($result) && $action !== Query::ACTION_SAVE && $action !== Query::ACTION_COUNTERS) {
         $response['statistics'] = $this->getCalculator()->statistics($result);
     }
     if ($action === Query::ACTION_POLL) {
         // return only the indicated sub-set of statistics
         $poll = $query->getPoll();
         if (empty($poll)) {
             throw new NumerologException('Poll command used with empty poll argument');
         } elseif (isset($response[$poll])) {
             $response = $response[$poll];
         } elseif (isset($response['statistics'][$poll])) {
             $response = $response['statistics'][$poll];
         } else {
             throw new NumerologException(sprintf('Invalid polling data requested: %s', $poll));
         }
     } else {
         $response['querytime'] = round((microtime(TRUE) - $time) * 1000, 5);
     }
     if ($action === Query::ACTION_SAVE && $tokenCreated) {
         $response['token'] = $token;
     }
     return $response;
 }