function save()
 {
     Assert::isFalse($this->isReadonly(), 'cannot save readonly collections');
     $getter = $this->referentialProperty->getGetter();
     $setter = $this->referentialProperty->getSetter();
     if ($this->referentialProperty->getMultiplicity()->isNullable()) {
         foreach ($this->getLostTracked() as $object) {
             $object->{$setter}(null);
             $object->save();
         }
     } else {
         if (sizeof($this->getLostTracked())) {
             $query = new EntityQuery($this->getChildren());
             $this->fillQuery($query);
             $query->andWhere(Expression::in($this->getChildren()->getLogicalSchema()->getIdentifier(), $this->getLostTracked()));
             $query->delete();
         }
     }
     foreach ($this->getList() as $object) {
         // avoid useless mutation
         if ($object->{$getter}() !== $this->getParentObject()) {
             $object->{$setter}($this->getParentObject());
         }
         $object->save();
     }
 }
 /**
  * @param OrmClass $ormClass object that represents a class to be generated
  * @param OrmProperty $ormProperty property that implements a ContainerPropertyType
  */
 function __construct(OrmClass $ormClass, OrmProperty $ormProperty)
 {
     $this->ormProperty = $ormProperty;
     $this->propertyType = $ormProperty->getType();
     Assert::isTrue($this->propertyType instanceof ContainerPropertyType);
     parent::__construct($ormClass);
 }
 public function parse($entryKey, &$whereClause, ParameterRegistry $parameters)
 {
     $this->property->parse($entryKey, $whereClause);
     $whereClause .= sprintf(" %s ", $this->operator);
     if ($this->expression instanceof OrmProperty) {
         $this->expression->parse($entryKey, $whereClause);
     } else {
         $whereClause .= sprintf("(%s)", $parameters->register($this->expression));
     }
 }
Example #4
0
 protected function getPropertyTuple(OrmProperty $property, array $tuple)
 {
     $propertyTuple = array();
     foreach ($property->getFields() as $field) {
         $propertyTuple[] = $tuple[$field];
     }
     $propertyType = $property->getType();
     $propertyTuple = array_combine(array_keys($propertyType->getSqlTypes()), $propertyTuple);
     return $propertyTuple;
 }
Example #5
0
 public function parse($entryKey, &$whereClause, ParameterRegistry $parameters)
 {
     $this->propertyName->parse($entryKey, $whereClause);
     if (null === $this->expression) {
         $whereClause .= " IS NOT NULL";
     } else {
         $whereClause .= " <> ";
         if ($this->expression instanceof OrmProperty) {
             $this->expression->parse($entryKey, $whereClause);
         } else {
             $whereClause .= $parameters->register($this->expression);
         }
     }
 }
Example #6
0
 private function insert(IdentifiableOrmEntity $entity)
 {
     $id = $entity->_getId();
     $idType = $this->identifier->getType();
     $generator = !$id && $idType instanceof IOrmEntityIdGenerator ? $idType->getIdGenerator($entity) : null;
     $generatorType = $generator ? $generator->getType() : null;
     if ($generatorType && $generatorType->isPre()) {
         $id = $generator->generate($entity);
         if ($id) {
             $entity->_setId($id);
         }
     }
     $affected = $this->executeQuery(InsertQuery::create($this->physicalSchema->getTable())->setValues($this->map->disassemble($entity)));
     if ($generatorType && $generatorType->isPost()) {
         $id = $generator->generate($entity);
         if ($id) {
             $entity->_setId($id);
         }
     }
     $this->identityMap->add($entity);
     $entity->setFetched();
 }
 /**
  * @return void
  */
 private function importProperty()
 {
     if (!sizeof($this->ormProperty->getFields())) {
         // columnless properties are skipped
         return;
     }
     $columns = array_combine($this->ormProperty->getFields(), $this->ormProperty->getType()->getSqlTypes());
     $dbColumns = array();
     foreach ($columns as $name => $dbType) {
         $dbColumns[$name] = new DBColumn($name, $dbType);
     }
     $fields = array_keys($dbColumns);
     $this->dbTable->addColumns($dbColumns);
     if ($this->ormProperty->getType() instanceof AssociationPropertyType) {
         $this->dbTable->addConstraint(new DBOneToOneConstraint($fields, $this->dbSchema->getTable($this->ormProperty->getType()->getContainer()->getTable()), $this->ormProperty->getType()->getAssociationBreakAction()));
     }
     if ($this->ormProperty->isIdentifier()) {
         $this->dbTable->addConstraint(new DBPrimaryKeyConstraint($fields));
     } else {
         if ($this->ormProperty->isUnique()) {
             $this->dbTable->addConstraint(new DBUniqueConstraint($fields));
         }
     }
 }
    function toGetter(IMappable $entity, OrmProperty $property)
    {
        $capitalizedPropertyName = ucfirst($property->getName());
        $class = $this->getContainerClassName($property);
        return <<<EOT
\t/**
\t * @return {$class}
\t */
\tfunction get{$capitalizedPropertyName}(\$readOnly = false)
\t{
\t\treturn new {$class}(\$this, \$readOnly);
\t}
EOT;
    }
Example #9
0
 /**
  * Adds the new property to the ORM-related entity
  *
  * @throws OrmModelIntegrityException if the property with the same name already added
  * @param OrmProperty $property
  *
  * @return OrmClass
  */
 function addProperty(OrmProperty $property)
 {
     $name = $property->getName();
     if (isset($this->properties[$name])) {
         throw new OrmModelIntegrityException("Property {$property->getName()} already defined");
     }
     $this->properties[$name] = $property;
     return $this;
 }
    /**
     * Create a php code which implements a field within the entity class
     * @param IMappable $entity
     * @param OrmProperty $property
     */
    function toField(IMappable $entity, OrmProperty $property)
    {
        $typeImpl = ($typeImpl = $this->getImplClass()) ? $typeImpl : 'scalar';
        if ($property->getMultiplicity()->isNullable()) {
            $typeImpl .= '|null';
        }
        return <<<EOT
\t/**
\t * @var {$typeImpl}
\t */
\tprotected \${$property->getName()};
EOT;
    }
    function toGetter(IMappable $entity, OrmProperty $property)
    {
        $returnValue = ($implClass = $this->getImplClass()) ? $implClass : 'mixed';
        if ($property->getMultiplicity()->isNullable()) {
            $returnValue .= '|null';
        }
        $propertyName = $property->getName();
        $capitalizedPropertyName = ucfirst($propertyName);
        return <<<EOT
\t/**
\t * @return {$returnValue}
\t */
\tfunction get{$capitalizedPropertyName}()
\t{
//\t\tif (\$this->{$propertyName}) { // thats is what called lazy fetching
//\t\t\t\$this->{$propertyName}->fetch();
//\t\t}

\t\treturn \$this->{$propertyName};
\t}
EOT;
    }
 private function importConstraints(OrmProperty $property)
 {
     $name = $this->dbTable->getName() . '_' . $property->getName();
     $fields = $property->getFields();
     if ($property->isIdentifier()) {
         $this->dbTable->addConstraint(new DBPrimaryKeyConstraint($name . '_pk', $this->dbTable, $fields));
     } else {
         if ($property->isUnique()) {
             $this->dbTable->addConstraint(new DBUniqueConstraint($name . '_uq', $this->dbTable, $fields));
         }
     }
     $type = $property->getType();
     if ($type instanceof AssociationPropertyType) {
         $this->dbTable->addConstraint(new DBOneToOneConstraint($name . '_fk', $this->dbTable, $fields, $this->dbSchema->getTable($property->getType()->getContainer()->getTable()), $property->getType()->getAssociationBreakAction()));
     } else {
         if ($type instanceof CompositePropertyType) {
             foreach ($type->getProperties($property) as $_property) {
                 $this->importConstraints($_property);
             }
         }
     }
     if ($property->isQueryable()) {
         $this->dbTable->addIndex(new DBIndex($name . '_idx', $this->dbTable, $fields));
     }
 }
 function __construct(IdentifiableOrmEntity $parent, IQueryable $children, OrmProperty $referentialProperty, $readOnly)
 {
     $this->mtm = $referentialProperty->getType();
     Assert::isTrue($this->mtm instanceof ManyToManyContainerPropertyType);
     parent::__construct($parent, $children, $readOnly);
 }
 /**
  * @return OrmProperty
  */
 private function generateContainer(OrmClass $type, SimpleXMLElement $xmlContainer)
 {
     $referredTypeName = (string) $xmlContainer['type'];
     if (!($referredType = $this->importEntity($referredTypeName))) {
         if (TypeUtils::isExists($referredTypeName) && TypeUtils::isInherits($referredTypeName, 'IDaoRelated')) {
             $referredType = call_user_func(array($referredTypeName, 'orm'));
         } else {
             $referrer = $type->getName() . '.' . (string) $xmlContainer['name'];
             throw new OrmModelIntegrityException($referrer . ' refers to unknown entity ' . $referredTypeName);
         }
     }
     try {
         // one-to-many
         $referredProperty = $referredType->getProperty((string) $xmlContainer['refs']);
         $propertyType = new OneToManyContainerPropertyType($type, $referredType, $referredProperty);
     } catch (OrmModelIntegrityException $e) {
         // many to many
         try {
             $proxy = $this->ormDomain->getClass((string) $xmlContainer['refs']);
         } catch (OrmModelIntegrityException $e) {
             $proxy = new OrmClass();
             $proxy->setHasDao(true);
             $proxy->setName((string) $xmlContainer['refs']);
             $this->ormDomain->addClass($proxy);
         }
         $propName = strtolower($type->getEntityName());
         try {
             $mtmType = new AssociationPropertyType($type, AssociationMultiplicity::exactlyOne(), AssociationBreakAction::cascade());
             $type_property = new OrmProperty($propName, $this->makeFields($type->getTable(), $mtmType), $mtmType, OrmPropertyVisibility::full(), AssociationMultiplicity::exactlyOne());
             $proxy->addProperty($type_property);
         } catch (OrmModelIntegrityException $e) {
             $type_property = $proxy->getProperty($propName);
         }
         $propName = strtolower($referredType->getEntityName());
         try {
             $mtmType = new AssociationPropertyType($referredType, AssociationMultiplicity::exactlyOne(), AssociationBreakAction::cascade());
             $referredType_property = new OrmProperty($propName, $this->makeFields($referredType->getTable(), $mtmType), $mtmType, OrmPropertyVisibility::full(), AssociationMultiplicity::exactlyOne());
             $proxy->addProperty($referredType_property);
         } catch (OrmModelIntegrityException $e) {
             $referredType_property = $proxy->getProperty($propName);
         }
         $propertyType = new ManyToManyContainerPropertyType($proxy, $type_property, $referredType_property);
     }
     $property = new OrmProperty((string) $xmlContainer['name'], array(), $propertyType, new OrmPropertyVisibility(OrmPropertyVisibility::READONLY), AssociationMultiplicity::zeroOrOne(), false);
     if (isset($xmlContainer['db-columns'])) {
         $property->setDBColumnNames($this->getFields($xmlContainer['db-columns']));
     }
     return $property;
 }
 protected function getCtorArgumentsPhpCode()
 {
     $proxyName = $this->proxy->getLogicalSchema()->getEntityName();
     return array($proxyName . '::orm()', $this->container->toPhpCall(), $this->encapsulant->toPhpCall());
 }
 protected function getCtorArgumentsPhpCode()
 {
     return array($this->getContainer()->getLogicalSchema()->getEntityName() . '::orm()', $this->getEncapsulant()->getLogicalSchema()->getEntityName() . '::orm()', $this->encapsulantProperty->toPhpCall());
 }
 /**
  * @return SqlColumn
  */
 function getSqlColumn()
 {
     $fields = $this->property->getFields();
     $field = reset($fields);
     return new SqlColumn($field, $this->owner);
 }
 /**
  * Gets the virtual property.
  *
  * This property is built in context of the owning property but contains inner info about
  * the composite property.
  *
  * This is needed because property type do not know about the database columns used to store
  * the value
  *
  * @param string $name name of the property to get from the composite type
  * @param OrmProperty $owner a property which owns the CompositePropertyType
  * @return OrmProperty
  */
 function getVirtualProperty($name, OrmProperty $owner)
 {
     $idx = 0;
     $found = false;
     foreach ($this->entity->getLogicalSchema()->getProperties() as $property) {
         if ($property->getName() == $name) {
             $found = true;
             break;
         }
         $idx += $property->getType()->getColumnCount();
     }
     if (!$found) {
         throw new OrmModelIntegrityException('property not found');
     }
     return new OrmProperty($name, array_slice($owner->getFields(), $idx, $property->getType()->getColumnCount()), $property->getType(), $property->getVisibility(), $property->getMultiplicity(), $property->isUnique(), $property->isIdentifier());
 }
 /**
  * @return void
  */
 private function join(OrmProperty $property, AssociationPropertyType $type, EntityQueryBuilder $builder, SelectQuerySource $source)
 {
     $joinMethod = $type->getAssociationMultiplicity()->is(AssociationMultiplicity::EXACTLY_ONE) ? SqlJoinMethod::INNER : SqlJoinMethod::LEFT;
     $condition = Expression::andChain();
     $srcSqlFields = $property->getFields();
     $dstSqlFields = $builder->entity->getLogicalSchema()->getIdentifier()->getFields();
     foreach ($srcSqlFields as $k => $v) {
         $condition->add(Expression::eq(new SqlColumn($srcSqlFields[$k], $this->alias), new SqlColumn($dstSqlFields[$k], $builder->alias)));
     }
     $source->join(new SqlConditionalJoin(new SelectQuerySource(new AliasedSqlValueExpression(new SqlIdentifier($builder->table), $builder->alias)), new SqlJoinMethod($joinMethod), $condition));
 }
    /**
     * @return void
     */
    private function fetchClassMembers(OrmProperty $property)
    {
        $visibility = $property->getVisibility();
        if ($visibility->is(OrmPropertyVisibility::TRANSPARENT)) {
            return;
        }
        $type = $property->getType();
        // make property itself
        $this->classProperties[] = $type->toField($this->ormClass, $property);
        // make setter
        if ($visibility->isSettable()) {
            $this->classMethods[] = $type->toSetter($this->ormClass, $property);
            if ($property->isIdentifier()) {
                $this->classMethods[] = <<<EOT
\tfunction _setId(\$id)
\t{
\t\t\$this->{$property->getSetter()}(\$id);

\t\treturn \$this;
\t}
EOT;
            }
        }
        // make getter
        if ($visibility->isGettable()) {
            $this->classMethods[] = $type->toGetter($this->ormClass, $property);
            if ($property->isIdentifier()) {
                $this->classMethods[] = <<<EOT
\tfunction _getId()
\t{
\t\treturn \$this->{$property->getGetter()}();
\t}
EOT;
            }
        }
    }