/** * Create indexes all at once * * This method may be useful if you want to create indexes all at once * or create indexes for already created tables. * * @return array (The array of classes and relationship tables with indexes created) * @access public */ public function createIndexes() { // initialize tables if (!$this->cmf || !$this->cm_obj_rel) { $this->initialize(); } // done if no classes at all if (!($cms = $this->cmf->allMade())) { return array(); } // array to hold classes/tables with indexes created $classes_done = array(); // go through all classes mapped foreach ($cms as $cm) { // get class name $class = $cm->getName(); // relation table dealt with for each class if ($class == $this->cm_obj_rel->getName()) { continue; } // don't try to create indexes twice if (!in_array($class, $classes_done)) { // create indexes on the class if ($db =& $this->_getDb($cm)) { $db->index($cm); $classes_done[] = $class; } } // create indexes on the object relations for the class foreach ($this->_getRelationPairs($class) as $base_a_b) { // don't try to create indexes twice if (in_array($base_a_b, $classes_done)) { continue; } // split base a and b list($base_a, $base_b) = split(' ', $base_a_b); // switch relation table $this->_setRelationTable($base_a, $base_b); // call db to create index if ($db =& $this->_getDb($this->cm_obj_rel)) { $db->index($this->cm_obj_rel); $classes_done[] = $base_a_b; } } } return $classes_done; }
/** * Constructor * @param string|epClassMap $class * @param string $alias * @param integer $type * @param epQueryAliasManager &$am */ public function __construct($class, $alias = false, $type = self::PRIMARY, &$am = false) { // call parent to set up alias manager parent::__construct($alias, $am); // set the class map to node if (is_string($class)) { // string (class name). call manage to get class map. $this->cm =& $this->_em()->getClassMap($class); } else { // class map otherwise $this->cm =& $class; } // set alias manager and database when constructing primary root if ($type == self::PRIMARY) { $this->_db($this->_em()->getDb($this->cm)); $this->_am($am); } // is alias is given? if ($alias) { // if yes, set class alias $this->_am()->setClassAlias($this->cm->getName(), $alias); } else { // otherwise, create one $alias = $this->_am()->getClassAlias($this->cm->getName()); } // set alias $this->alias = $alias; // set alias as the name of the node $this->setName($this->alias); // set root type $this->type = $type; }
/** * Returns the class::var name for a var * @params string $var_name * @return string */ protected function _varName($var) { $class = ''; if ($this->ep_cm) { $class = $this->ep_cm->getName() . '::'; } return $class . $var; }
/** * Parse the comment of the var (field) * @param string $var the name of the var * @param string $comment the comment associated to the var * @return epFieldMap */ protected function parseVarComment($var, $comment) { $class_var = $this->cm->getName() . '::' . $var; // parse var comment $c = new epComment($comment); if (!$c) { throw new epExceptionParser('Cannot parse comment for var [' . $class_var . ']'); return false; } // get the @orm tag value if (!($value = $c->getTagValue('orm'))) { //warn('No @orm tag for var [' . $class_var . ']. Ignored.'); return false; } // parse var tag if (!($t = new epVarTag())) { throw new epExceptionParser('Cannot parse @orm tag for var [' . $class_var . ']'); return false; } $error = $t->parse($value); if (is_string($error)) { throw new epExceptionParser('Error in parsing @orm tag for var [' . $class_var . ']: ' . $error); return false; } // call field map factory to create a field map if (!($fm = epFieldMapFactory::make($var, $t->get('type'), $t->get('params')))) { return false; } // always harvest 'raw' customer tags $fm->setTags($c->getTags()); // set column name if set if ($column_name = $t->get('name')) { $fm->setColumnName($column_name); } // get key type if ($key_type = $t->get('keytype')) { // get key name if (!($key_name = $t->get('keyname'))) { $key_name = $var; } switch ($key_type) { case 'unique': $this->cm->addUniqueKey($key_name, $var); break; case 'index': $this->cm->addIndexKey($key_name, $var); break; } } return $fm; }
/** * Converts the last record set into uoids * @param epClassMap $cm the class map for the conversion * @param array (of integers) object ids to be excluded * @return false|array (of uoids) * @throws epExceptionDbObject */ protected function _rs2uoid($cm, $oids_ex = null) { // !!!important!!! with a large db, the list of oid to be excluded // $oids_ex can grown really large and can significantly slow down // queries. so it is suppressed in the select statement and moved // to this method to process. // get the class name $class = $cm->getName(); // reset counter and return value $ret = array(); // go through reach record $okay = $this->db->rsRestart(); while ($okay) { // get oid column $oid = $this->db->rsGetCol($cn = $cm->getOidColumn(), $class . '.' . $cn); // exclude it? if ($oids_ex && in_array($oid, $oids_ex)) { // next row $okay = $this->db->rsNext(); // exclude it continue; } // get class_b $class_b = $this->db->rsGetCol('class_b', $class . '.' . 'class_b'); // get oid_b $oid_b = $this->db->rsGetCol('oid_b', $class . '.' . 'oid_b'); // collect return result $ret[] = $class_b . ':' . $oid_b; // next row $okay = $this->db->rsNext(); } return $ret; }
/** * Returns the relation ids for the variable specified of the object * @param epObject $o the object * @param epFieldMap $fm the field map of the variable * @param epClassMap $cm the class map of the object * @return false|string|array */ public function getRelationIds(&$o, $fm, $cm) { // make sure we are dealing with valid object and non-primitive field if (!$o || !$fm || !$cm) { return false; } // object needs to have a valid id and has to be non-primitive if (!($oid_a = $o->epGetObjectId())) { return false; } // get class_a, var_a, and the related class $base_a = $fm->getClassMap()->getName(); $class_a = $cm->getName(); $var_a = $fm->getName(); $base_b = $fm->getClass(); if (!$base_a || !$class_a || !$var_a || !$base_b) { throw new epExceptionManager('Cannot find related class for var [' . $class_a . '::' . $var_a . ']'); return false; } // switch relations table $this->_setRelationTable($base_a, $base_b); // make an example relation objects if (!($eo =& $this->_relationExample($class_a, $oid_a, $var_a, $base_b))) { return false; } // find all relation objects using the example object $rs =& parent::find($eo, EP_GET_FROM_DB, false); // find from db only, false no cache // convert result into oids $oids_b = null; if ($fm->isSingle()) { if (is_array($rs) && count($rs) > 1) { throw new epExceptionManager('Field ' . $fm->getName() . ' mapped as composed_of_/has_one but is associated with > 1 objects'); return false; } if ($rs) { $oids_b = $this->_encodeClassOid($rs[0]->get_class_b(), $rs[0]->get_oid_b()); } } else { if ($fm->isMany()) { $oids_b = array(); if ($rs) { foreach ($rs as $r) { $oids_b[] = $this->_encodeClassOid($r->get_class_b(), $r->get_oid_b()); } } } } return $oids_b; }
/** * Converts the last record set into epObject object(s) with class map * @param epClassMap $cm the class map for the conversion * @param array (of integers) object ids to be excluded * @return false|array (of epObject) * @throws epExceptionDbObject */ protected function &_rs2obj($cm, $ex = null) { // !!!important!!! with a large db, the list of oid to be excluded // $ex can grown really large and can significantly slow down // queries. so it is suppressed in the select statement and moved // to this method to process. // get epManager instance and cache it if (!$this->ep_m) { $this->ep_m =& epManager::instance(); } // get the class name $class = $cm->getName(); // get all mapped vars if (!($fms = $cm->getAllFields())) { return self::$false; } // reset counter and return value $ret = array(); // go through reach record $okay = $this->db->rsRestart(); while ($okay) { // get oid column $oid = $this->db->rsGetCol($cn = $cm->getOidColumn(), $class . '.' . $cn); // exclude it? if ($ex && in_array($oid, $ex)) { // next row $okay = $this->db->rsNext(); // exclude it continue; } // call epManager to create an instance (false: no caching; false: no event dispatching) if (!($o =& $this->ep_m->_create($class, false, false))) { // next row $okay = $this->db->rsNext(); continue; } // go through each field foreach ($fms as $fname => $fm) { // skip non-primivite field if (!$fm->isPrimitive()) { continue; } // get var value and set to object $val = $this->db->rsGetCol($cn = $fm->getColumnName(), $class . '.' . $cn); // set value to var (true: no dirty flag change) $o->epSet($fm->getName(), $this->_castType($val, $fm->getType()), true); } // set oid $o->epSetObjectId($oid); // collect return result $ret[] = $o; // next row $okay = $this->db->rsNext(); } return $ret; }
/** * Gets the class (name) of the object * @return string */ public function epGetClass() { return $this->ep_cm ? $this->ep_cm->getName() : get_class($this->ep_object); }
/** * Parse the comment of the var (field) * @param string $var the name of the var * @param string $comment the comment associated to the var * @return epFieldMap */ protected function parseVarComment($var, $comment) { $class_var = $this->cm->getName() . '::' . $var; // parse var comment $c = new epComment($comment); if (!$c) { throw new epExceptionParser('Cannot parse comment for var [' . $class_var . ']'); return false; } // get the @orm tag value if (!($value = $c->getTagValue('orm'))) { //warn('No @orm tag for var [' . $class_var . ']. Ignored.'); return false; } // parse var tag if (!($t = new epVarTag($value))) { throw new epExceptionParser('Cannot parse @orm tag for var [' . $class_var . ']'); return false; } // call field map factory to create a field map if (!($fm = epFieldMapFactory::make($var, $t->get('type'), $t->get('params')))) { return false; } // set column name if set if ($column_name = $t->get('name')) { $fm->setColumnName($column_name); } return $fm; }