/**
  * 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);
 }
Example #3
0
 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'));
 }
Example #4
0
 /**
  * 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;
             }
         }
     }
 }
Example #5
0
 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;
         }
     }
 }
Example #7
0
 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;
 }
Example #8
0
 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);
         }
     }
 }