Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[1.6] Added ARRAY column type (refs #135)

  • Loading branch information...
commit f632d24396b70ae2addcf25d2df021de1e677430 1 parent 34fbfdc
@fzaninotto fzaninotto authored
View
4 generator/lib/builder/om/ObjectBuilder.php
@@ -60,6 +60,8 @@ protected function addColumnAccessorMethods(&$script)
$this->addTemporalAccessor($script, $col);
} else if ($col->getType() === PropelTypes::OBJECT) {
$this->addObjectAccessor($script, $col);
+ } else if ($col->getType() === PropelTypes::PHP_ARRAY) {
+ $this->addArrayAccessor($script, $col);
} else {
$this->addDefaultAccessor($script, $col);
}
@@ -85,6 +87,8 @@ protected function addColumnMutatorMethods(&$script)
$this->addTemporalMutator($script, $col);
} else if ($col->getType() === PropelTypes::OBJECT) {
$this->addObjectMutator($script, $col);
+ } else if ($col->getType() === PropelTypes::PHP_ARRAY) {
+ $this->addArrayMutator($script, $col);
} else {
$this->addDefaultMutator($script, $col);
}
View
72 generator/lib/builder/om/PHP5ObjectBuilder.php
@@ -367,7 +367,7 @@ protected function addColumnAttributes(&$script)
$this->addColumnAttributeLoaderComment($script, $col);
$this->addColumnAttributeLoaderDeclaration($script, $col);
}
- if ($col->getType() == PropelTypes::OBJECT) {
+ if ($col->getType() == PropelTypes::OBJECT || $col->getType() == PropelTypes::PHP_ARRAY) {
$this->addColumnAttributeUnserializedComment($script, $col);
$this->addColumnAttributeUnserializedDeclaration($script, $col);
}
@@ -923,6 +923,50 @@ protected function addObjectAccessorBody(&$script, Column $col)
}
/**
+ * Adds an array getter method.
+ * @param string &$script The script will be modified in this method.
+ * @param Column $col The current column.
+ * @see parent::addColumnAccessors()
+ */
+ protected function addArrayAccessor(&$script, Column $col)
+ {
+ $this->addDefaultAccessorComment($script, $col);
+ $this->addDefaultAccessorOpen($script, $col);
+ $this->addArrayAccessorBody($script, $col);
+ $this->addDefaultAccessorClose($script, $col);
+ }
+
+ /**
+ * Adds the function body for an array accessor method
+ * @param string &$script The script will be modified in this method.
+ * @param Column $col The current column.
+ * @see addDefaultAccessor()
+ **/
+ protected function addArrayAccessorBody(&$script, Column $col)
+ {
+ $cfc = $col->getPhpName();
+ $clo = strtolower($col->getName());
+ $cloUnserialized = $clo.'_unserialized';
+ if ($col->isLazyLoad()) {
+ $script .= "
+ if (!\$this->".$clo."_isLoaded && \$this->$clo === null && !\$this->isNew()) {
+ \$this->load$cfc(\$con);
+ }
+";
+ }
+
+ $script .= "
+ if (null === \$this->$cloUnserialized) {
+ \$this->$cloUnserialized = array();
+ }
+ if (!\$this->$cloUnserialized && null !== \$this->$clo) {
+ \$$cloUnserialized = substr(\$this->$clo, 2, -2);
+ \$this->$cloUnserialized = \$$cloUnserialized ? explode(' | ', \$$cloUnserialized) : array();
+ }
+ return \$this->$cloUnserialized;";
+ }
+
+ /**
* Adds a normal (non-temporal) getter method.
* @param string &$script The script will be modified in this method.
* @param Column $col The current column.
@@ -1434,6 +1478,32 @@ protected function addObjectMutator(&$script, Column $col)
}
/**
+ * Adds a setter for Array columns.
+ * @param string &$script The script will be modified in this method.
+ * @param Column $col The current column.
+ * @see parent::addColumnMutators()
+ */
+ protected function addArrayMutator(&$script, Column $col)
+ {
+ $clo = strtolower($col->getName());
+ $cloUnserialized = $clo.'_unserialized';
+ $this->addMutatorOpen($script, $col);
+
+ $script .= "
+ if (\$this->$cloUnserialized !== \$v";
+ if (($def = $col->getDefaultValue()) !== null && !$def->isExpression()) {
+ $script .= " || \$this->isNew()";
+ }
+ $script .= ") {
+ \$this->$cloUnserialized = \$v;
+ \$this->$clo = '| ' . implode(' | ', \$v) . ' |';
+ \$this->modifiedColumns[] = ".$this->getColumnConstant($col).";
+ }
+";
+ $this->addMutatorClose($script, $col);
+ }
+
+ /**
* Adds setter method for "normal" columns.
* @param string &$script The script will be modified in this method.
* @param Column $col The current column.
View
21 generator/lib/builder/om/QueryBuilder.php
@@ -619,7 +619,26 @@ public function filterBy$colPhpName(\$$variableName = null, \$comparison = null)
if (is_object(\$$variableName)) {
\$$variableName = serialize(\$$variableName);
}";
- } elseif ($col->isTextType()) {
+ } elseif ($col->getType() == PropelTypes::PHP_ARRAY) {
+ $script .= "
+ if (null === \$comparison || \$comparison == Criteria::CONTAINS) {
+ if (is_scalar(\$$variableName)) {
+ \$$variableName = '%| ' . \$$variableName . ' |%';
+ \$comparison = Criteria::LIKE;
+ }
+ } elseif (\$comparison == Criteria::NOT_CONTAINS) {
+ \$$variableName = '%| ' . \$$variableName . ' |%';
+ \$comparison = Criteria::NOT_LIKE;
+ \$key = \$this->getAliasedColName($qualifiedName);
+ if(\$this->containsKey(\$key)) {
+ \$this->addAnd(\$key, \$$variableName, \$comparison);
+ } else {
+ \$this->addAnd(\$key, \$$variableName, \$comparison);
+ }
+ \$this->addOr(\$key, null, Criteria::ISNULL);
+ return \$this;
+ }";
+ } elseif ($col->isTextType()) {
$script .= "
if (null === \$comparison) {
if (is_array(\$$variableName)) {
View
5 generator/lib/model/PropelTypes.php
@@ -44,6 +44,7 @@ class PropelTypes
const BOOLEAN = "BOOLEAN";
const BOOLEAN_EMU = "BOOLEAN_EMU";
const OBJECT = "OBJECT";
+ const PHP_ARRAY = "ARRAY";
private static $TEXT_TYPES = array(
self::CHAR, self::VARCHAR, self::LONGVARCHAR, self::CLOB, self::DATE, self::TIME, self::TIMESTAMP, self::BU_DATE, self::BU_TIMESTAMP
@@ -91,6 +92,7 @@ class PropelTypes
const BOOLEAN_NATIVE_TYPE = "boolean";
const BOOLEAN_EMU_NATIVE_TYPE = "boolean";
const OBJECT_NATIVE_TYPE = "";
+ const PHP_ARRAY_NATIVE_TYPE = "array";
/**
* Mapping between Propel types and PHP native types.
@@ -124,6 +126,7 @@ class PropelTypes
self::BOOLEAN => self::BOOLEAN_NATIVE_TYPE,
self::BOOLEAN_EMU => self::BOOLEAN_EMU_NATIVE_TYPE,
self::OBJECT => self::OBJECT_NATIVE_TYPE,
+ self::PHP_ARRAY => self::PHP_ARRAY_NATIVE_TYPE,
);
/**
@@ -156,6 +159,7 @@ class PropelTypes
self::BOOLEAN => self::BOOLEAN,
self::BOOLEAN_EMU => self::BOOLEAN_EMU,
self::OBJECT => self::OBJECT,
+ self::PHP_ARRAY => self::PHP_ARRAY,
// These are pre-epoch dates, which we need to map to String type
// since they cannot be properly handled using strtotime() -- or even numeric
// timestamps on Windows.
@@ -194,6 +198,7 @@ class PropelTypes
self::BOOLEAN => PDO::PARAM_BOOL,
self::BOOLEAN_EMU => PDO::PARAM_INT,
self::OBJECT => PDO::PARAM_STR,
+ self::PHP_ARRAY => PDO::PARAM_STR,
// These are pre-epoch dates, which we need to map to String type
// since they cannot be properly handled using strtotime() -- or even numeric
View
1  generator/lib/platform/MssqlPlatform.php
@@ -44,6 +44,7 @@ protected function initialize()
$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "VARBINARY(MAX)"));
$this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "VARBINARY(MAX)"));
$this->setSchemaDomainMapping(new Domain(PropelTypes::OBJECT, "VARCHAR(MAX)"));
+ $this->setSchemaDomainMapping(new Domain(PropelTypes::PHP_ARRAY, "VARCHAR(MAX)"));
}
public function getMaxColumnNameLength()
View
1  generator/lib/platform/MysqlPlatform.php
@@ -40,6 +40,7 @@ protected function initialize()
$this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "LONGTEXT"));
$this->setSchemaDomainMapping(new Domain(PropelTypes::TIMESTAMP, "DATETIME"));
$this->setSchemaDomainMapping(new Domain(PropelTypes::OBJECT, "TEXT"));
+ $this->setSchemaDomainMapping(new Domain(PropelTypes::PHP_ARRAY, "TEXT"));
}
/**
View
3  generator/lib/platform/OraclePlatform.php
@@ -46,7 +46,8 @@ protected function initialize()
$this->setSchemaDomainMapping(new Domain(PropelTypes::BINARY, "LONG RAW"));
$this->setSchemaDomainMapping(new Domain(PropelTypes::VARBINARY, "BLOB"));
$this->setSchemaDomainMapping(new Domain(PropelTypes::LONGVARBINARY, "LONG RAW"));
- $this->setSchemaDomainMapping(new Domain(PropelTypes::OBJECT, "NVARCHAR2", "2000"));
+ $this->setSchemaDomainMapping(new Domain(PropelTypes::OBJECT, "NVARCHAR2", "2000"));
+ $this->setSchemaDomainMapping(new Domain(PropelTypes::PHP_ARRAY, "NVARCHAR2", "2000"));
}
View
1  generator/lib/platform/PgsqlPlatform.php
@@ -40,6 +40,7 @@ protected function initialize()
$this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "BYTEA"));
$this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "TEXT"));
$this->setSchemaDomainMapping(new Domain(PropelTypes::OBJECT, "TEXT"));
+ $this->setSchemaDomainMapping(new Domain(PropelTypes::PHP_ARRAY, "TEXT"));
}
public function getNativeIdMethod()
View
1  generator/lib/platform/SqlitePlatform.php
@@ -35,6 +35,7 @@ protected function initialize()
$this->setSchemaDomainMapping(new Domain(PropelTypes::BLOB, "LONGBLOB"));
$this->setSchemaDomainMapping(new Domain(PropelTypes::CLOB, "LONGTEXT"));
$this->setSchemaDomainMapping(new Domain(PropelTypes::OBJECT, "MEDIUMTEXT"));
+ $this->setSchemaDomainMapping(new Domain(PropelTypes::PHP_ARRAY, "MEDIUMTEXT"));
}
/**
View
15 generator/lib/util/PropelQuickBuilder.php
@@ -84,6 +84,7 @@ public function build($dsn = null, $user = null, $pass = null, $adapter = null)
$adapter = new DBSQLite();
}
$con = new PropelPDO($dsn, $user, $pass);
+ $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$this->buildSQL($con);
$this->buildClasses();
$name = $this->getDatabase()->getName();
@@ -104,7 +105,19 @@ public function getDatabase()
public function buildSQL(PDO $con)
{
- return PropelSQLParser::executeString($this->getSQL(), $con);
+ $statements = PropelSQLParser::parseString($this->getSQL());
+ foreach ($statements as $statement) {
+ if (strpos($statement, 'DROP') === 0) {
+ // drop statements cause errors since the table doesn't exist
+ continue;
+ }
+ $stmt = $con->prepare($statement);
+ if ($stmt instanceof PDOStatement) {
+ // only execute if has no error
+ $stmt->execute();
+ }
+ }
+ return count($statements);
}
public function getSQL()
View
12 generator/resources/dtd/database.dtd
@@ -82,12 +82,12 @@ PHP class or method name.
required (true|false) "false"
type
(
- BIT | TINYINT | SMALLINT | INTEGER | BIGINT | FLOAT
- | REAL | NUMERIC | DECIMAL | CHAR | VARCHAR | LONGVARCHAR
- | DATE | TIME | TIMESTAMP | BINARY | VARBINARY | LONGVARBINARY
- | NULL | OTHER | PHP_OBJECT | DISTINCT | STRUCT | ARRAY
- | BLOB | CLOB | REF | BOOLEANINT | BOOLEANCHAR
- | DOUBLE | BOOLEAN | OBJECT
+ BIT | TINYINT | SMALLINT | INTEGER | BIGINT | FLOAT
+ | REAL | NUMERIC | DECIMAL | CHAR | VARCHAR | LONGVARCHAR
+ | DATE | TIME | TIMESTAMP | BINARY | VARBINARY | LONGVARBINARY
+ | NULL | OTHER | PHP_OBJECT | DISTINCT | STRUCT | ARRAY
+ | BLOB | CLOB | REF | BOOLEANINT | BOOLEANCHAR
+ | DOUBLE | BOOLEAN | OBJECT | ARRAY
) "VARCHAR"
phpType CDATA #IMPLIED
sqlType CDATA #IMPLIED
View
2  generator/resources/xsd/database.xsd
@@ -41,7 +41,6 @@
<xs:enumeration value="OTHER"/>
<xs:enumeration value="DISTINCT"/>
<xs:enumeration value="STRUCT"/>
- <xs:enumeration value="ARRAY"/>
<xs:enumeration value="BLOB"/>
<xs:enumeration value="CLOB"/>
<xs:enumeration value="REF"/>
@@ -50,6 +49,7 @@
<xs:enumeration value="DOUBLE"/>
<xs:enumeration value="BOOLEAN"/>
<xs:enumeration value="OBJECT"/>
+ <xs:enumeration value="ARRAY"/>
</xs:restriction>
</xs:simpleType>
View
6 runtime/lib/query/Criteria.php
@@ -54,6 +54,12 @@ class Criteria implements IteratorAggregate
/** Comparison type. */
const NOT_LIKE = " NOT LIKE ";
+ /** Comparison for array column types */
+ const CONTAINS = "CONTAINS";
+
+ /** Comparison for array column types */
+ const NOT_CONTAINS = "NOT_CONTAINS";
+
/** PostgreSQL comparison type */
const ILIKE = " ILIKE ";
View
8 runtime/lib/query/ModelCriteria.php
@@ -1895,16 +1895,16 @@ public function getAliasedColName($colName)
* Overrides Criteria::add() to force the use of a true table alias if it exists
*
* @see Criteria::add()
- * @param string $column The colName of column to run the comparison on (e.g. BookPeer::ID)
+ * @param string $column The colName of column to run the condition on (e.g. BookPeer::ID)
* @param mixed $value
- * @param string $comparison A String.
+ * @param string $operator A String, like Criteria::EQUAL.
*
* @return ModelCriteria A modified Criteria object.
*/
- public function addUsingAlias($p1, $value = null, $comparison = null)
+ public function addUsingAlias($p1, $value = null, $operator = null)
{
$key = $this->getAliasedColName($p1);
- return $this->containsKey($key) ? $this->addAnd($key, $value, $comparison) : $this->add($key, $value, $comparison);
+ return $this->containsKey($key) ? $this->addAnd($key, $value, $operator) : $this->add($key, $value, $operator);
}
/**
View
4 runtime/lib/util/PropelColumnTypes.php
@@ -46,7 +46,8 @@ class PropelColumnTypes
BU_TIMESTAMP = "BU_TIMESTAMP",
BOOLEAN = "BOOLEAN",
BOOLEAN_EMU = "BOOLEAN_EMU",
- OBJECT = "OBJECT";
+ OBJECT = "OBJECT",
+ PHP_ARRAY = "ARRAY";
private static $propelToPdoMap = array(
self::CHAR => PDO::PARAM_STR,
@@ -75,6 +76,7 @@ class PropelColumnTypes
self::BOOLEAN => PDO::PARAM_BOOL,
self::BOOLEAN_EMU => PDO::PARAM_INT,
self::OBJECT => PDO::PARAM_STR,
+ self::PHP_ARRAY => PDO::PARAM_STR,
);
/**
View
31 test/testsuite/generator/builder/om/GeneratedObjectComplexTypesTest.php
@@ -23,7 +23,7 @@ class GeneratedObjectComplexTypeTest extends PHPUnit_Framework_TestCase
public function testObjectColumnType()
{
$schema = <<<EOF
-<database name="generated_object_complex_type_test">
+<database name="generated_object_complex_type_test_1">
<table name="complex_column_type_entity_1">
<column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
<column name="bar" type="OBJECT" />
@@ -45,6 +45,35 @@ public function testObjectColumnType()
$e = ComplexColumnTypeEntity1Query::create()->findOne();
$this->assertEquals($c, $e->getBar(), 'object columns are persisted');
}
+
+ public function testArrayColumnType()
+ {
+ $schema = <<<EOF
+<database name="generated_object_complex_type_test_2">
+ <table name="complex_column_type_entity_2">
+ <column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
+ <column name="bar" type="ARRAY" />
+ </table>
+</database>
+EOF;
+ //$builder = new PropelQuickBuilder();
+ //$builder->setSchema($schema);
+ //echo $builder->getSQL();
+ //exit();
+ PropelQuickBuilder::buildSchema($schema);
+ $e = new ComplexColumnTypeEntity2();
+ $this->assertequals(array(), $e->getBar(), 'array columns return an empty array by default');
+ $value = array('foo', 1234);
+ $e->setBar($value);
+ $this->assertEquals($value, $e->getBar(), 'array columns can store arrays');
+ $e->setBar(array());
+ $this->assertEquals(array(), $e->getBar(), 'object columns can be reset');
+ $e->setBar($value);
+ $e->save();
+ ComplexColumnTypeEntity2Peer::clearInstancePool();
+ $e = ComplexColumnTypeEntity2Query::create()->findOne();
+ $this->assertEquals($value, $e->getBar(), 'array columns are persisted');
+ }
}
class FooColumnValue
View
50 test/testsuite/generator/builder/om/GeneratedQueryComplexTypesTest.php
@@ -23,7 +23,7 @@ class GeneratedQueryComplexTypeTest extends PHPUnit_Framework_TestCase
public function testObjectColumnType()
{
$schema = <<<EOF
-<database name="generated_query_complex_type_test">
+<database name="generated_query_complex_type_test_10">
<table name="complex_column_type_entity_10">
<column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
<column name="bar" type="OBJECT" />
@@ -54,6 +54,54 @@ public function testObjectColumnType()
$e = ComplexColumnTypeEntity10Query::create()->filterByBar($c1, Criteria::NOT_EQUAL)->findOne();
$this->assertEquals($e2, $e, 'object columns are searchable by object and accept a comparator');
}
+
+ public function testArrayColumnType()
+ {
+ $schema = <<<EOF
+<database name="generated_query_complex_type_test_11">
+ <table name="complex_column_type_entity_11">
+ <column name="id" primaryKey="true" type="INTEGER" autoIncrement="true" />
+ <column name="bar" type="ARRAY" />
+ </table>
+</database>
+EOF;
+ PropelQuickBuilder::buildSchema($schema);
+ $e0 = new ComplexColumnTypeEntity11();
+ $e0->save();
+ $e1 = new ComplexColumnTypeEntity11();
+ $e1->setBar(array('foo', 'bar', 'baz'));
+ $e1->save();
+ $e2 = new ComplexColumnTypeEntity11();
+ $e2->setBar(array('bar'));
+ $e2->save();
+ $e3 = new ComplexColumnTypeEntity11();
+ $e3->setBar(array('bar23'));
+ $e3->save();
+ $e = ComplexColumnTypeEntity11Query::create()->findPk($e1->getPrimaryKey());
+ $this->assertEquals(array('foo', 'bar', 'baz'), $e->getBar(), 'array columns are correctly hydrated');
+ $e = ComplexColumnTypeEntity11Query::create()->filterByBar('bar')->orderById()->find();
+ $this->assertEquals($e1, $e[0], 'array columns are searchable by element');
+ $this->assertEquals(array('foo', 'bar', 'baz'), $e[0]->getBar(), 'array columns are searchable by element');
+ $this->assertEquals($e2, $e[1], 'array columns are searchable by element');
+ $this->assertEquals(array('bar'), $e[1]->getBar(), 'array columns are searchable by element');
+ $this->assertEquals(2, $e->count(), 'array columns do not return false positives');
+ $e = ComplexColumnTypeEntity11Query::create()->filterByBar('bar23')->findOne();
+ $this->assertEquals($e3, $e, 'array columns are searchable by element');
+ $e = ComplexColumnTypeEntity11Query::create()
+ ->filterByBar('bar', Criteria::CONTAINS)
+ ->orderById()
+ ->find();
+ $this->assertEquals(2, $e->count(), 'array columns are searchable by element using Criteria::CONTAINS');
+ $this->assertEquals($e1, $e[0], 'array columns are searchable by element using Criteria::CONTAINS');
+ $this->assertEquals($e2, $e[1], 'array columns are searchable by element using Criteria::CONTAINS');
+ $e = ComplexColumnTypeEntity11Query::create()
+ ->filterByBar('bar', Criteria::NOT_CONTAINS)
+ ->orderById()
+ ->find();
+ $this->assertEquals(2, $e->count(), 'array columns are searchable by element using Criteria::NOT_CONTAINS');
+ $this->assertEquals($e0, $e[0], 'array columns are searchable by element using Criteria::NOT_CONTAINS');
+ $this->assertEquals($e3, $e[1], 'array columns are searchable by element using Criteria::NOT_CONTAINS');
+ }
}
class FooColumnValue2
Please sign in to comment.
Something went wrong with that request. Please try again.