public function xtestSetup()
 {
     $db = $this->getDb();
     $table = $this->getTable(__FUNCTION__);
     $_id_list = $this->addRows($db, $table, 5);
     ///$where_criteria = new MingoCriteria();
     ///$where_criteria->ninFoo(1,2);
     ///$where_criteria->is_q('foo:(-1 -2)');
     $list = $db->getQuery('foo NOT foo:(1 2)', array('table' => $table));
     out::e($list);
     $this->assertEquals(3, count($list));
     $this->assureSubset($list, $_id_list);
     return;
     $db = $this->getDb();
     $table = $this->getTable(__FUNCTION__);
     ///$table = new MingoTable(__FUNCTION__);
     $_id_list = array();
     for ($i = 0; $i < 5; $i++) {
         $map = array('foo' => $i);
         $map = $db->set($table, $map);
         $_id_list[] = (string) $map['_id'];
     }
     //for
     out::e($_id_list);
     $c = new MingoCriteria();
     $c->in_id($_id_list);
     $list = $db->get($table, $c);
     out::e($list);
     $count = $db->getCount($table, $c);
     out::e($count);
     ///$db->getQuery('_id:(1z4ddb7b390b5b1759137267 OR 6z4ddb7b39119fc745281592)',array('table' => $table));
 }
Example #2
0
 /**
  *  test the criteria ->has* magic method
  *  
  *  @since  11-8-10
  */
 public function testHas()
 {
     $c = new MingoCriteria();
     $this->assertFalse($c->hasFoo());
     $c->isFoo(1);
     $this->assertTrue($c->hasFoo());
     $this->assertFalse($c->hasBar());
     $c->gteBar(2);
     $this->assertTrue($c->hasBar());
     $this->assertTrue($c->hasFoo());
 }
Example #3
0
 /**
  *  merge one MingoCriteria instance into this MingoCriteria instance
  *  
  *  @since  1-3-12      
  *  @param  \MingoCriteria  $criteria the criteria to merge into this one
  *  @return self
  */
 public function merge(MingoCriteria $criteria)
 {
     $this->command_symbol = $criteria->getCommandSymbol();
     $this->map_where = $criteria->getWhere();
     $this->map_sort = $criteria->getSort();
     $this->field_map = $criteria->getFields();
     if ($criteria->hasLimit()) {
         $this->setLimit($criteria->getLimit());
     }
     //if
     if ($criteria->hasPage()) {
         $this->setPage($criteria->getPage());
     }
     //if
     if ($criteria->hasOffset()) {
         $this->setOffset($criteria->getOffset());
     }
     //if
     return $this;
 }
Example #4
0
 /**
  *  this should be used to take the generic $where_criteria and turn it into something
  *  the interface can use (eg, for a SQL interface, the $where_criteria would be turned
  *  into a valid SQL string).
  *  
  *  @param  MingoTable  $table    
  *  @param  MingoCriteria $where_criteria   
  *  @return mixed return whatever you want, however you want to return it, whatever is easiest for you
  */
 protected function normalizeCriteria(MingoTable $table, MingoCriteria $where_criteria = null)
 {
     $ret_map = array();
     $ret_map['select_str'] = '*';
     $ret_map['table_str'] = $this->normalizeTableSQL($table);
     $ret_map['where_criteria'] = $where_criteria;
     $ret_map['where_str'] = '';
     $ret_map['where_params'] = array();
     $ret_map['sort_str'] = '';
     $ret_map['limit_str'] = '';
     $ret_map['limit'] = array(0, 0);
     // canary
     if (empty($where_criteria)) {
         return $ret_map;
     }
     //if
     $ret_where = $ret_sort = '';
     $criteria_where = $where_criteria->getWhere();
     $criteria_sort = $where_criteria->getSort();
     $command_symbol = $where_criteria->getCommandSymbol();
     foreach ($criteria_where as $name => $map) {
         $where_sql = '';
         $where_val = array();
         $name_sql = $this->normalizeNameSQL($name);
         if (is_array($map)) {
             $total_map = count($map);
             // go through each map val and append it to the sql string...
             foreach ($map as $command => $val) {
                 if ($where_criteria->isCommand($command)) {
                     $command_bare = $where_criteria->getCommand($command);
                     $command_sql = '';
                     $command_val = array();
                     // build the sql...
                     if (isset($this->method_map[$command_bare])) {
                         $symbol = empty($this->method_map[$command_bare]['symbol']) ? '' : $this->method_map[$command_bare]['symbol'];
                         if (!empty($this->method_map[$command_bare]['arg'])) {
                             $callback = $this->method_map[$command_bare]['arg'];
                             list($command_sql, $command_val) = $this->{$callback}($symbol, $name_sql, $map[$command]);
                         }
                         //if
                         list($where_sql, $where_val) = $this->appendSql('AND', $command_sql, $command_val, $where_sql, $where_val);
                     }
                     //if
                 } else {
                     throw new UnexpectedValueException(sprintf('there is an error in the internal structure of your %s instance', get_class($where_criteria)));
                 }
                 //if/else
             }
             //foreach
             // we want to parenthesize the sql since there was more than one value for the field
             if ($total_map > 1) {
                 $where_sql = sprintf(' (%s)', trim($where_sql));
             }
             //if
         } else {
             // we have a NAME=VAL (an is* method call)...
             list($where_sql, $where_val) = $this->normalizeValSql('=', $name_sql, $map);
         }
         //if/else
         list($ret_map['where_str'], $ret_map['where_params']) = $this->appendSql('AND', $where_sql, $where_val, $ret_map['where_str'], $ret_map['where_params']);
     }
     //foreach
     if (!empty($ret_map['where_params'])) {
         $ret_map['where_str'] = sprintf('WHERE%s', $ret_map['where_str']);
     }
     //if
     // build the sort sql...
     foreach ($criteria_sort as $name => $direction) {
         $name_sql = $this->normalizeNameSQL($name);
         $dir_sql = $direction > 0 ? 'ASC' : 'DESC';
         if (empty($ret_map['sort_sql'])) {
             $ret_map['sort_str'] = sprintf('ORDER BY %s %s', $name_sql, $dir_sql);
         } else {
             $ret_map['sort_str'] = sprintf('%s,%s %s', $ret_map['sort_sql'], $name_sql, $dir_sql);
         }
         //if/else
     }
     //foreach
     $ret_map = $this->normalizeLimitCriteria($ret_map, $where_criteria->getLimit(), $where_criteria->getOffset());
     return $ret_map;
 }
Example #5
0
 /**
  *  this should be used to take the generic $where_criteria and turn it into something
  *  the interface can use (eg, for a SQL interface, the $where_criteria would be turned
  *  into a valid SQL string).
  *  
  *  currently not supported: 'near'
  *      
  *  @link http://lucene.apache.org/java/2_4_0/queryparsersyntax.html
  *      
  *  @param  MingoTable  $table    
  *  @param  MingoCriteria $where_criteria   
  *  @return mixed return whatever you want, however you want to return it, whatever is easiest for you
  */
 protected function normalizeCriteria(MingoTable $table, MingoCriteria $where_criteria = null)
 {
     $ret_map = array();
     $ret_map['where_criteria'] = $where_criteria;
     $ret_map['limit'] = array(0, 0);
     $query = new Zend_Search_Lucene_Search_Query_Boolean();
     if ($where_criteria !== null) {
         // add all the required search keys and their values...
         $criteria_where = $where_criteria->getWhere();
         foreach ($criteria_where as $name => $map) {
             $subquery = null;
             $where_sql = '';
             $where_val = array();
             $required = true;
             if (is_array($map)) {
                 $command = $where_criteria->normalizeCommand('in');
                 if (isset($map[$command])) {
                     $subquery = $this->handleMulti($name, $map[$command], true);
                     $required = true;
                 }
                 //if
                 // according to: http://lucene.apache.org/java/2_4_0/queryparsersyntax.html
                 // Lucene cannot do nin queries without something before it (eg, foo:1 NOT foo(2 3) but
                 // (NOT foo(2 3) doesn't work)
                 $command = $where_criteria->normalizeCommand('nin');
                 if (isset($map[$command])) {
                     $subquery = $this->handleMulti($name, $map[$command], false);
                     $required = false;
                 }
                 //if
                 $command = $where_criteria->normalizeCommand('not');
                 if (isset($map[$command])) {
                     $subquery = $this->handleEquals($name, $map[$command], false);
                 }
                 //if
                 $command1 = $where_criteria->normalizeCommand('gte');
                 $command2 = $where_criteria->normalizeCommand('lte');
                 if (isset($map[$command1]) && isset($map[$command2])) {
                     $subquery = $this->handleRange($name, $map[$command1], $map[$command2], true);
                 }
                 //if
                 if (isset($map[$command1])) {
                     $subquery = $this->handleRange($name, $map[$command1], null, true);
                 }
                 //if
                 if (isset($map[$command2])) {
                     $subquery = $this->handleRange($name, null, $map[$command2], true);
                 }
                 //if
                 $command = $where_criteria->normalizeCommand('gt');
                 if (isset($map[$command])) {
                     $subquery = $this->handleRange($name, $map[$command], null, false);
                 }
                 //if
                 $command = $where_criteria->normalizeCommand('lt');
                 if (isset($map[$command])) {
                     $subquery = $this->handleRange($name, null, $map[$command], false);
                 }
                 //if
             } else {
                 if ($name === '_q') {
                     $subquery = Zend_Search_Lucene_Search_QueryParser::parse($map);
                 } else {
                     $subquery = $this->handleEquals($name, $map, true);
                 }
                 //if/else
             }
             //if/else
             if ($subquery) {
                 $query->addSubquery($subquery, $required);
             }
             //method
         }
         //foreach
         // limit offset...
         $offset = $where_criteria->getOffset();
         $ret_map['limit'] = array($where_criteria->getLimit() + $offset, $offset);
         // caution from docs:
         // Please use caution when using a non-default search order;
         // the query needs to retrieve documents completely from an index,
         // which may dramatically reduce search performance.
         // http://framework.zend.com/manual/en/zend.search.lucene.searching.html#zend.search.lucene.searching.sorting
         if ($where_criteria->hasSort()) {
             $criteria_sort = $where_criteria->getSort();
             $sort_list = array();
             // build the sort sql...
             foreach ($criteria_sort as $name => $direction) {
                 $sort_list[] = $name;
                 $sort_list[] = SORT_REGULAR;
                 ///$sort_list[] = SORT_STRING; ///SORT_NUMERIC;
                 $sort_list[] = $direction > 0 ? SORT_ASC : SORT_DESC;
             }
             //foreach
             $ret_map['sort'] = $sort_list;
         }
         //if
     }
     //if
     $ret_map['query'] = $query;
     return $ret_map;
 }
Example #6
0
 /**
  *  do an integrity check on the fields
  *  
  *  @since  12-9-11      
  *  @param  MingoTable  $table
  *  @param  array $map  the key/value map that will be added to $table  
  *  @return array the $map with the best fields possible
  */
 protected function assureFields(MingoTable $table, array $map)
 {
     // do some checks on the fields...
     foreach ($table->getFields() as $field_name => $field) {
         if ($field->isRequired()) {
             if (!array_key_exists($field_name, $map)) {
                 $req_field_val = $field->getDefaultVal();
                 if ($req_field_val !== null) {
                     $map[$field_name] = $req_field_val;
                 } else {
                     throw new DomainException(sprintf('cannot set() because $map is missing required field: [%s]', $field_name));
                 }
                 //if/else
             }
             //if
         }
         //if
         if ($field->isUnique()) {
             if (isset($map[$field_name])) {
                 $where_criteria = new MingoCriteria();
                 $where_criteria->isField($field_name, $map[$field_name]);
                 if ($this->getOne($table, $where_criteria)) {
                     throw new DomainException(sprintf('cannot set() on table %s because field [%s] with value [%s] is not unique', $table->getName(), $field_name, $map[$field_name]));
                 }
                 //if
             }
             //if
         }
         //if
     }
     //foreach
     return $map;
 }
Example #7
0
 /**
  *  make sure an Interface can be serialized and unserialized and work
  *      
  *  @since  10-3-11
  */
 public function testSerialize()
 {
     $db = $this->getDb();
     $table = $this->getTable(__FUNCTION__);
     $_id_list = $this->insert($table, 1);
     $sdb = serialize($db);
     $this->assertInternalType('string', $sdb);
     $db2 = unserialize($sdb);
     $where_criteria = new MingoCriteria();
     $where_criteria->in_Id($_id_list);
     $list = $db2->get($table, $where_criteria);
     $this->assertNotEmpty($list);
     foreach ($list as $map) {
         $this->assertContains($map['_id'], $_id_list);
     }
     //foreach
 }
Example #8
0
 /**
  *  find the index table name from the table and the list of fields the index comprises
  *  
  *  @param  MingoTable  $table  the main table's name
  *  @param  MingoCriteria $where_criteria   
  *  @return string  the index table name
  */
 protected function findIndexTableName(MingoTable $table, MingoCriteria $where_criteria)
 {
     if (!$where_criteria->hasWhere() && !$where_criteria->hasSort()) {
         return '';
     }
     //if
     $ret_str = '';
     $is_match = false;
     $where_map = $where_criteria->getWhere();
     $sort_map = $where_criteria->getSort();
     // php >= 5.3, use when Mingo is ported to namespaces...
     ///$field_list = array_keys(array_replace($where_map,$sort_map));
     // we need to get a list of all the fields used in the order they will be used
     $field_list = array_keys($where_map);
     if (!empty($sort_map)) {
         $field_list = array_unique(array_merge($field_list, array_keys($sort_map)));
     }
     //if
     // now go through the index and see if it matches all the fields...
     foreach ($table->getIndexes() as $index) {
         $field_i = 0;
         foreach ($index->getFieldNames() as $field) {
             if (isset($field_list[$field_i])) {
                 if ($field === $field_list[$field_i]) {
                     $is_match = true;
                     $field_i++;
                 } else {
                     $is_match = false;
                     break;
                 }
                 //if/else
             } else {
                 break;
             }
             //if/else
         }
         //foreach
         if ($is_match) {
             // we're done, we found a match...
             $ret_str = $this->getIndexTableName($table, $index);
             break;
         }
         //if
     }
     //foreach
     if (!$is_match) {
         // since we couldn't find an index table, make sure the query can be valid
         // on the main table
         // we are selecting on the main table (no index is being used) so we can only
         // select or sort on 4 fields (by default): _id, _created, and _updated
         foreach ($field_list as $field) {
             // if a field in the where map is not in the main table we've got trouble
             // since an index table couldn't be found
             if (!in_array($field, $this->non_body_fields)) {
                 $e_msg = sprintf('Could not match fields: [%s] sorted by fields: [%s] with an index table.', join(',', array_keys($where_map)), join(',', array_keys($sort_map)));
                 // list the available index tables if we are in debug mode...
                 if ($this->hasDebug()) {
                     $e_msg .= ' Indexes available: ';
                     $index_list = $this->getIndexes($table);
                     $e_index_list = array();
                     foreach ($index_list as $index) {
                         $e_index_list[] = sprintf('%s(%s)', $index->getName(), join(',', $index->getFieldNames()));
                     }
                     //foreach
                     $e_msg .= join(', ', $e_index_list);
                 }
                 //if
                 throw new RuntimeException($e_msg);
             }
             //if
         }
         //foreach
     }
     //if/else
     return $ret_str;
 }