/** * Processes a query interpolating properties * @param string $q query to process * @return string processed query */ public function processQuery($q) { preg_match_all(self::IDENTIFIER_PATTERN, $q, $matches, PREG_SET_ORDER); // check if it's an update statement $update = stripos(trim($q), 'UPDATE') === 0; // get the table names $aliased = array(); foreach ($matches as $key => $m) { // clear braces $str = substr($m[0], 1, -1); // if it's an aliased class if (strpos($str, ' ') !== false) { $tmp = explode(' ', $str); $aliased[$tmp[1]] = $tmp[0]; $q = str_replace($m[0], $this->config->getEntity($tmp[0])->table . ' ' . $tmp[1], $q); // if it's a non-aliased class } elseif (strpos($str, '.') === false) { // if it's a non-aliased class $table = $this->config->getEntity($str)->table; $aliased[$table] = $str; $q = str_replace($m[0], $table, $q); } } // update references to the properties foreach ($matches as $key => $m) { // clear braces $str = substr($m[0], 1, -1); // if it's a property if (strpos($str, '.') !== false) { list($en, $prop) = explode('.', $str); // if it's an alias if (isset($aliased[$en])) { $entity = $aliased[$en]; $alias = $en; } else { $entity = $en; $alias = $this->config->getEntity($entity)->table; } $propconf = $this->config->getEntity($entity)->getProperty($prop); // if it's an update statement, // we must not include the table if ($update) { // skip if it's an sql field if (!isset($propconf[2]) || !isset($propconf[2]['sql'])) { $col = $propconf[0]; } } else { // if it's an sql field if (isset($propconf[2]) && isset($propconf[2]['sql'])) { $col = '(' . $this->processSubQuery($propconf[2]['sql'], $entity, $alias) . ')'; } else { $col = $alias . '.' . $propconf[0]; } } $q = str_replace($m[0], $col, $q); } } return $q; }
protected function _createConfig($tableName = null, $properties = null, $subclasses = null, $discriminator = null, $discriminatorValue) { $config = array('connection' => array('pdo' => $this->getSQLiteInMemoryPDOConnection(), 'dialect' => 'sqlite'), 'classes' => array($this->entityName => array())); if ($tableName !== null) { $config['classes'][$this->entityName]['table'] = $tableName; } if ($properties !== null) { $config['classes'][$this->entityName]['props'] = $properties; } if ($subclasses !== null) { $config['classes'][$this->entityName]['subclasses'] = $subclasses; } if ($discriminator !== null) { $config['classes'][$this->entityName]['discriminator'] = $discriminator; } if ($discriminatorValue !== null) { $config['classes'][$this->entityName]['discriminator-value'] = $discriminatorValue; } $this->config = new OutletConfig($config); return $this->config->getEntity($this->entityName); }
public function testCanGetEntityConfig() { $config = new OutletConfig(array('connection' => array('pdo' => $this->getSQLiteInMemoryPDOConnection(), 'dialect' => 'sqlite'), 'classes' => array('Testing' => array('table' => 'testing', 'props' => array('id' => array('id', 'int', array('pk' => true))))))); $this->assertThat($config->getEntity('Testing'), $this->isInstanceOf('OutletEntityConfig')); }
/** * Construct a new instance of OutletEntityConfig * @param OutletConfig $config outlet configuration * @param object $entity entity * @param object $conf configuration * @return OutletEntityConfig instance */ function __construct(OutletConfig $config, $entity, array $conf) { $this->config = $config; if (!isset($conf['table'])) { throw new OutletConfigException('Mapping for entity [' . $entity . '] is missing element [table]'); } if (!isset($conf['props'])) { throw new OutletConfigException('Mapping for entity [' . $entity . '] is missing element [props]'); } // i need to leave this for for the outletgen script //if (!class_exists($entity)) throw new OutletConfigException('Class does not exist for mapped entity ['.$entity.']'); // validate that there's a pk foreach ($conf['props'] as $p => $f) { if (@$f[2]['pk']) { $pk = $p; break; } } if (!isset($pk)) { throw new OutletConfigException("Entity [{$entity}] must have at least one column defined as a primary key in the configuration"); } // save basic data $this->table = $conf['table']; $this->clazz = $entity; $this->props = $conf['props']; $this->sequenceName = isset($conf['sequenceName']) ? $conf['sequenceName'] : ''; $this->useGettersAndSetters = isset($conf['useGettersAndSetters']) ? $conf['useGettersAndSetters'] : $config->useGettersAndSetters(); // Adjusts sequence name for postgres if it is not specified if ($config->getConnection()->getDialect() == 'pgsql' && $this->sequenceName == '') { foreach ($this->props as $key => $d) { // Property needs to be primary key and auto increment if (isset($d[2]['pk']) && $d[2]['pk'] && (isset($d[2]['autoIncrement']) && $d[2]['autoIncrement'])) { // default name for sequence = {table}_{column}_seq $this->sequenceName = $this->table . '_' . $d[0] . '_seq'; break; } } } }
function __construct(OutletConfig $config, $entity, array $conf) { // $this->config = $config; if (!isset($conf['table'])) { throw new OutletConfigException('Mapping for entity [' . $entity . '] is missing element [table]'); } if (!isset($conf['props'])) { throw new OutletConfigException('Mapping for entity [' . $entity . '] is missing element [props]'); } // i need to leave this for for the outletgen script //if (!class_exists($entity)) throw new OutletConfigException('Class does not exist for mapped entity ['.$entity.']'); // validate that there's a pk $this->props = array(); $this->pks = array(); foreach ($conf['props'] as $propName => $propConf) { $propConf = new OutletPropertyConfig($propName, $propConf); $this->props[$propName] = $propConf; if ($propConf->isPK()) { $this->pks[$propName] = $propConf; } } if (count($this->pks) == 0) { throw new OutletConfigException("Entity [{$entity}] must have at least one column defined as a primary key in the configuration"); } // save basic data $this->table = $conf['table']; $this->clazz = $entity; // $this->props = $conf['props']; $this->sequenceName = isset($conf['sequenceName']) ? $conf['sequenceName'] : ''; $this->useGettersAndSetters = isset($conf['useGettersAndSetters']) ? $conf['useGettersAndSetters'] : $config->useGettersAndSetters(); }
/** * Construct a new instance of OutletEntityConfig * @param OutletConfig $config outlet configuration * @param object $entity entity * @param object $conf configuration * @return OutletEntityConfig instance */ function __construct(OutletConfig $config, $entity, array $conf) { $this->config = $config; if (!isset($conf['table'])) { throw new OutletConfigException('Mapping for entity [' . $entity . '] is missing element [table]'); } if (!isset($conf['props'])) { throw new OutletConfigException('Mapping for entity [' . $entity . '] is missing element [props]'); } // i need to leave this for for the outletgen script //if (!class_exists($entity)) throw new OutletConfigException('Class does not exist for mapped entity ['.$entity.']'); // validate that there's a pk foreach ($conf['props'] as $p => $f) { if (@$f[2]['pk']) { $pk = $p; break; } } if (!isset($pk)) { throw new OutletConfigException("Entity [{$entity}] must have at least one column defined as a primary key in the configuration"); } // save basic data $this->table = $conf['table']; $this->clazz = $entity; $this->props = $conf['props']; $this->sequenceName = isset($conf['sequenceName']) ? $conf['sequenceName'] : ''; $this->useGettersAndSetters = isset($conf['useGettersAndSetters']) ? $conf['useGettersAndSetters'] : $config->useGettersAndSetters; // if there's a plural defined at the foreign entity // else use the entity plus an 's' $this->plural = isset($conf['plural']) ? $conf['plural'] : $this->clazz . 's'; // Adjusts sequence name for postgres if it is not specified if ($config->getConnection()->getDialect() == 'pgsql' && $this->sequenceName == '') { foreach ($this->props as $key => $d) { // Property needs to be primary key and auto increment if (isset($d[2]['pk']) && $d[2]['pk'] && (isset($d[2]['autoIncrement']) && $d[2]['autoIncrement'])) { // default name for sequence = {table}_{column}_seq $this->sequenceName = $this->table . '_' . $d[0] . '_seq'; break; } } } // load associations if (isset($conf['associations'])) { foreach ($conf['associations'] as $assoc) { switch ($assoc[0]) { case 'one-to-many': $a = new OutletOneToManyConfig($this->config, $this->clazz, $assoc[1], $assoc[2]); break; case 'many-to-one': $a = new OutletManyToOneConfig($this->config, $this->clazz, $assoc[1], $assoc[2]); break; case 'many-to-many': $a = new OutletManyToManyConfig($this->config, $this->clazz, $assoc[1], $assoc[2]); break; case 'one-to-one': $a = new OutletOneToOneConfig($this->config, $this->clazz, $assoc[1], $assoc[2]); break; default: $a = new OutletAssociationConfig($this->config, $assoc[0], $this->clazz, $assoc[1], $assoc[2]); } $this->associations[] = $a; } } }
public function parse($query) { preg_match_all('/\\{[a-zA-Z0-9_]+(( |\\.)[a-zA-Z0-9_]+)*\\}/', $query, $matches, PREG_SET_ORDER); // check if it's an update statement $update = stripos(trim($query), 'UPDATE') === 0; // get the table names $aliased = array(); foreach ($matches as $key => $m) { // clear braces $str = substr($m[0], 1, -1); // if it's an aliased class if (strpos($str, ' ') !== false) { $tmp = explode(' ', $str); $aliased[$tmp[1]] = $tmp[0]; $query = str_replace($m[0], $this->conf->getEntity($tmp[0])->getTable() . ' ' . $tmp[1], $query); // if it's a non-aliased class } elseif (strpos($str, '.') === false) { $table = $this->conf->getEntity($str)->getTable(); $aliased[$table] = $str; $query = str_replace($m[0], $table, $query); } } // update references to the properties foreach ($matches as $key => $m) { // clear braces $str = substr($m[0], 1, -1); // if it's a property if (strpos($str, '.') !== false) { list($en, $prop) = explode('.', $str); // if it's an alias if (isset($aliased[$en])) { $entity = $aliased[$en]; // check for the existence of the field configuration $propertyConfig = $this->conf->getEntity($entity)->getProperty($prop); $col = $en . '.' . $propertyConfig->getField(); } else { $entity = $en; $entityConfig = $this->conf->getEntity($entity, false); if ($entityConfig === null) { throw new OutletException('String [' . $entity . '] is not a valid entity or alias, check your query'); } // if it's an update statement, // we must not include the table if ($update) { $propertyConfig = $this->conf->getEntity($entity)->getProperty($prop); $col = $propertyConfig->getField(); } else { $table = $entityConfig->getTable(); $propconf = $entityConfig->getProperty($prop); // if it's an sql field // if (isset($propconf[2]) && isset($propconf[2]['sql'])) { // $col = $propconf[2]['sql'] .' as ' . $propconf[0]; // } else { $col = $table . '.' . $propconf->getField(); // } } } $query = str_replace($m[0], $col, $query); } } return $query; }
function __construct(OutletConfig $config, $entity, array $conf, OutletEntityConfig $superConfig = null) { // $this->config = $config; if ($superConfig !== null) { $this->superConfig = $superConfig; $this->isSubclass = true; } if (!$this->isSubclass && !isset($conf['table'])) { throw new OutletConfigException('Mapping for entity [' . $entity . '] is missing element [table]'); } if (!isset($conf['props'])) { throw new OutletConfigException('Mapping for entity [' . $entity . '] is missing element [props]'); } // i need to leave this for for the outletgen script //if (!class_exists($entity)) throw new OutletConfigException('Class does not exist for mapped entity ['.$entity.']'); // validate that there's a pk $this->props = array(); $this->allprops = array(); $this->subclasses = array(); $this->pks = array(); foreach ($conf['props'] as $propName => $propConf) { $propConf = new OutletPropertyConfig($propName, $propConf); $this->props[$propName] = $propConf; $this->allprops[$propName] = $propConf; if ($superConfig !== null) { $superConfig->allprops[$propName] = $propConf; } if (!$this->isSubclass && $propConf->isPK()) { $this->pks[$propName] = $propConf; } } if (!$this->isSubclass && count($this->pks) == 0) { throw new OutletConfigException("Entity [{$entity}] must have at least one column defined as a primary key in the configuration"); } if ($this->isSubclass) { foreach ($this->superConfig->getProperties() as $prop) { $this->props[$prop->getName()] = $prop; $this->allprops[$prop->getName()] = $prop; } } if ($this->isSubclass) { $this->pks = $this->superConfig->getPkProperties(); $this->table = $this->superConfig->getTable(); $this->discriminator = $this->superConfig->getDiscriminator(); $this->discriminatorValue = $conf['discriminator-value']; } else { $this->table = $conf['table']; } // save basic data $this->clazz = $entity; // $this->props = $conf['props']; $this->sequenceName = isset($conf['sequenceName']) ? $conf['sequenceName'] : ''; $this->useGettersAndSetters = isset($conf['useGettersAndSetters']) ? $conf['useGettersAndSetters'] : $config->useGettersAndSetters(); if (isset($conf['subclasses'])) { if (!isset($conf['discriminator'])) { throw new OutletConfigException('Mapping for entity [' . $key . '] is specifying subclasses but it is missing element [discriminator]'); } if (!isset($conf['discriminator-value'])) { throw new OutletConfigException('Mapping for entity [' . $key . '] is specifying subclasses but it is missing element [discriminator-value]'); } $this->discriminator = new OutletPropertyConfig('discriminator', $conf['discriminator']); $this->discriminatorValue = $conf['discriminator-value']; $this->allprops[$this->discriminator->getName()] = $this->discriminator; foreach ($conf['subclasses'] as $className => $classConf) { if (!isset($classConf['discriminator-value'])) { throw new OutletConfigException('Mapping for entity [' . $className . '] is specifying subclasses but it is missing element [discriminator-value]'); } $subentity = new OutletEntityConfig($config, $className, $classConf, $this); $this->subclasses[$subentity->getDiscriminatorValue()] = $subentity; $config->addEntity($subentity); } } }