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)); } }
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; }
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); } } }
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; }
/** * 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; } } }