Example #1
0
 /**
  * Override {@link epDbPort::checkIndex()}
  * @param epClassMap $cm
  * @param epDb $db
  * @return false|array
  */
 public function checkIndex($cm, $db)
 {
     // reset counter and return value
     $ret = array(array(), array());
     // get all columns in the pg_attribute and pg_class table
     $sql = 'SELECT a.attname, a.attnum ' . ' FROM pg_attribute a, pg_class c ' . ' WHERE c.relname = ' . $db->quote($cm->getTable()) . ' AND a.attrelid = c.oid AND a.attnum > 0' . ' ORDER BY a.attnum';
     // execute the query
     if (!$db->execute($sql)) {
         return false;
     }
     // array to collect all columns
     $columns = array();
     // go through reach record
     $okay = $this->db->rsRestart();
     while ($okay) {
         $num = $db->rsGetCol('attnum');
         $name = $db->rsGetCol('attname');
         $columns[$num] = $name;
         $okay = $this->db->rsNext();
     }
     // get all the indexes in the table (indkey has a list, space separated)
     $sql = 'SELECT c2.relname AS indexname, i.indisprimary, i.indisunique, i.indkey AS indkey' . ' FROM pg_class c, pg_class c2, pg_index i' . ' WHERE c.relname = ' . $db->quote($cm->getTable()) . ' AND c.oid = i.indrelid AND i.indexrelid = c2.oid';
     // execute above query
     if (!$db->execute($sql)) {
         return false;
     }
     // go through reach record
     $okay = $db->rsRestart();
     while ($okay) {
         // skip the primary index
         if ($this->db->rsGetCol('indisprimary') == 't') {
             // next row
             $okay = $this->db->rsNext();
             continue;
         }
         // get index name
         $name = $this->db->rsGetCol('indexname');
         $unique = $this->db->rsGetCol('indisunique');
         // $unique is t if unique
         // $unique is f if index
         $unique = $unique == 't' ? 0 : 1;
         $indexes = explode(' ', $this->db->rsGetCol('indkey'));
         foreach ($indexes as $index) {
             $ret[$unique][$name][] = $columns[$index];
         }
         // next row
         $okay = $db->rsNext();
     }
     return $ret;
 }
Example #2
0
 /**
  * Override {@link epDbPort::checkIndex()}
  * @param epClassMap $cm
  * @param epDb $db
  * @return false|array
  */
 public function checkIndex($cm, $db)
 {
     // get index list
     $sql = 'PRAGMA index_list(' . $db->quoteId($cm->getTable()) . ')';
     if (!$db->execute($sql)) {
         return false;
     }
     // reset counter and return value
     $ret = array(array(), array());
     $indexes = array();
     $uniques = array();
     // go through reach record
     $okay = $db->rsRestart();
     while ($okay) {
         // get index name
         $name = $db->rsGetCol('name');
         $unique = $db->rsGetCol('unique');
         // $unique is 1 if unique
         // $unique is 0 if index
         $unique = !$unique;
         // ???
         // store the index name for further information
         $indexes[] = $name;
         $uniques[$name] = $unique;
         $ret[$unique][$name] = array();
         // next row
         $okay = $db->rsNext();
     }
     // go through each index
     foreach ($indexes as $index) {
         $sql = 'PRAGMA index_info(' . $db->quoteId($index) . ')';
         if (!$db->execute($sql)) {
             return false;
         }
         // go through reach record
         $okay = $db->rsRestart();
         while ($okay) {
             // get index name
             $column = $db->rsGetCol('name');
             $ret[$uniques[$index]][$index][] = $column;
             // next row
             $okay = $db->rsNext();
         }
     }
     return $ret;
 }
 /**
  * Override {@link epDbPort::createTable()}
  * 
  * Generate SQL code to create table
  * 
  * @param epClassMap $cm
  * @param string $indent
  * @param epDb $db
  * @return string|array (of strings)
  */
 public function createTable($cm, $db, $indent = '  ')
 {
     // start create table
     $sql = "CREATE TABLE " . $db->quoteId($cm->getTable()) . " (";
     // the oid field
     $fstr = $this->_defineField($db->quoteId($cm->getOidColumn()), 'INTEGER', '12', false, true);
     $sql .= $fstr . ",";
     // write sql for each field
     foreach ($cm->getAllFields() as $fname => $fm) {
         if ($fm->isPrimitive()) {
             // get the field definition
             $fstr = $this->_defineField($db->quoteId($fm->getColumnName()), $fm->getType(), $fm->getTypeParams(), $fm->getDefaultValue(), false);
             $sql .= $fstr . ",";
         }
     }
     // remove the last ','
     $sql = substr($sql, 0, strlen($sql) - 1);
     // end of table creation
     $sql .= ");";
     return $sql;
 }
 /**
  * Generate SQL code to create table
  * 
  * Sometimes extra procedure may be needed for some fields to work. 
  * For example, some database does not have a direct auto-incremental 
  * keyword and, to make it work, you need extra procedure after 
  * creating the table. Here is an example, for a table column in 
  * an Oracle database to be auto-incremental, we need to insert 
  * a sequence and a trigger (See this link for more info 
  * {@link http://webxadmin.free.fr/article.php?i=134}). If this is 
  * the case the subclass should override this method and return both
  * "create table" statement and the extra.
  * 
  * @param epClassMap $cm
  * @param epDb $db
  * @param string $indent
  * @return string|array (of strings)
  */
 public function createTable($cm, $db, $indent = '  ')
 {
     // start create table
     $sql = "CREATE TABLE " . $db->quoteId($cm->getTable()) . " (\n";
     // the oid field
     $fstr = $this->_defineField($db->quoteId($cm->getOidColumn()), 'integer', '12', false, true);
     $sql .= $indent . $fstr . ",\n";
     // write sql for each field
     foreach ($cm->getAllFields() as $fname => $fm) {
         if ($fm->isPrimitive()) {
             // get the field definition
             $fstr = $this->_defineField($db->quoteId($fm->getColumnName()), $fm->getType(), $fm->getTypeParams(), $fm->getDefaultValue(), false);
             $sql .= $indent . $fstr . ",\n";
         }
     }
     // write primary key
     $sql .= $indent . "PRIMARY KEY (" . $db->quoteId($cm->getOidColumn()) . ")\n";
     // end of table creation
     $sql .= ");\n";
     return $sql;
 }
 /**
  * Returns the base (root) field map 
  * @return null|epFieldMap
  */
 protected function &getBase()
 {
     // return cached one
     if ($this->base) {
         return $this->base;
     }
     // class map exists?
     if (!$this->class_map) {
         return self::$false;
     }
     // get the base
     if (!($this->base = $this->class_map->getBaseField($this->name))) {
         $this->base = $this;
     }
     return $this->base;
 }
 /**
  * Override {@link epDbPort::createTable()}
  *
  * Generate SQL code to create table
  *
  * @param epClassMap $cm
  * @param string $indent
  * @param epDb $db
  * @return string|array (of strings)
  */
 public function createTable($cm, $db, $indent = '  ')
 {
     // start create table
     $sql = "CREATE TABLE \"" . $cm->getTable() . "\" (";
     $sql = $sql . "CONSTRAINT " . $cm->getTable() . "_" . $cm->getOidColumn() . " PRIMARY KEY (" . $cm->getOidColumn() . "),";
     // the oid field
     $fstr = $this->_defineField($cm->getOidColumn(), 'Integer', '', false, true);
     $sql .= $fstr . ",";
     // write sql for each field
     foreach ($cm->getAllFields() as $fname => $fm) {
         if ($fm->isPrimitive()) {
             // get the field definition
             $fstr = $this->_defineField($db->quoteId($fm->getColumnName()), $fm->getType(), $fm->getTypeParams(), $fm->getDefaultValue(), false);
             $sql .= $fstr . ",";
         }
     }
     // remove the last ','
     $sql = substr($sql, 0, strlen($sql) - 1);
     // end of table creation
     // WITH OIDS - see http://www.ezpdo.net/forum/viewtopic.php?pid=750#p750
     $sql .= ") WITH OIDS;";
     return $sql;
 }
 /**
  * Return the '<table> as <alias>' part for the SQL FROM clause
  * @return string 
  */
 public function getTableAlias()
 {
     // quote ids
     $table = $this->quoteId($this->cm->getTable());
     $alias = $this->quoteId($this->alias);
     // return sql
     return "{$table} AS {$alias}";
 }
Example #8
0
 /**
  * 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;
 }
Example #9
0
 /**
  * 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;
 }
Example #10
0
 /**
  * SQL to create unique keys
  * @param epClassMap $cm
  * @param epDb $db
  * @param string $indent
  * @return string
  */
 protected function _uniqueKeys($cm, $db, $indent = '  ')
 {
     $sql = '';
     foreach ($cm->getUniqueKeys() as $name => $key) {
         // quote keys
         foreach ($key as $k => $v) {
             $key[$k] = $db->quoteId($v);
         }
         // get stmt for this key
         $sql .= $indent . $this->_uniqueKey($db->quoteId($name), $key) . ",\n";
     }
     return $sql;
 }
Example #11
0
 /**
  * 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;
 }
 /**
  * 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;
 }
Example #13
0
 /**
  * Change table name for object relations class 
  * @param string $base_a
  * @param string $base_b
  * @return void
  */
 protected function _setRelationTable($base_a, $base_b)
 {
     $this->cm_obj_rel->setTable($this->getRelationTable($base_a, $base_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;
 }
Example #15
0
 /**
  * Returns the field map for the variable 
  * Note that param $var_name will be replaced with the best matched var name
  * @param string $var_name
  * @return false|epFieldMap
  */
 protected function &_getFieldMap($var_name)
 {
     // check if we have class map
     if (!$this->ep_cm || !$var_name) {
         return self::$false;
     }
     // check if field map is cached
     if (isset($this->ep_fms[$var_name])) {
         return $this->ep_fms[$var_name];
     }
     // get field map
     $fm = $this->ep_cm->getField($var_name);
     // cache it
     $this->ep_fms[$var_name] = $fm;
     // return the field map for the var
     return $fm;
 }
Example #16
0
 /**
  * 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;
 }