Skip to content

Instantly share code, notes, and snippets.

@beberlei
Created October 6, 2009 20:03
Show Gist options
  • Save beberlei/203359 to your computer and use it in GitHub Desktop.
Save beberlei/203359 to your computer and use it in GitHub Desktop.
<?php
require_once "ezc/Base/base.php";
require_once "Zend/Loader/Autoloader.php";
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->pushAutoloader(array('ezcBase', 'autoload'), 'ezc');
class EntitySchemaProvider extends Zend_Tool_Framework_Provider_Abstract
{
/**
* @var array
*/
private $_types = array(
Zend_Entity_Definition_Property::TYPE_INT => 'integer',
Zend_Entity_Definition_Property::TYPE_STRING => 'text',
Zend_Entity_Definition_Property::TYPE_BOOLEAN => 'boolean',
Zend_Entity_Definition_Property::TYPE_FLOAT => 'float',
Zend_Entity_Definition_Property::TYPE_DATE => 'date',
Zend_Entity_Definition_Property::TYPE_DATETIME => 'datetime',
Zend_Entity_Definition_Property::TYPE_TIMESTAMP => 'integer',
Zend_Entity_Definition_Property::TYPE_TEXT => 'clob',
Zend_Entity_Definition_Property::TYPE_BINARY => 'blob',
);
/**
* @var array
*/
private $_databasesDDLGenerators = array(
'oracle' => 'ezcDbSchemaOracleWriter',
'mysql' => 'ezcDbSchemaMysqlWriter',
'pgsql' => 'ezcDbSchemaPgsqlWriter',
'sqlite' => 'ezcDbSchemaSqliteWriter',
);
/**
* Generate DDL statements of a given database from a metadata directory.
*
* @param string $dir
* @param string $database
*/
public function generate($dir, $database)
{
if(!array_key_exists($database, $this->_databasesDDLGenerators)) {
throw new Exception("Unknown database format given: '".$database."'");
}
$metadata = new Zend_Entity_MetadataFactory_Code($dir);
$metadata->transform('Zend_Db_Mapper_Mapping');
$tables = array();
foreach($metadata->getDefinitionEntityNames() AS $entityName) {
/* @var $mapping Zend_Db_Mapper_Mapping */
$mapping = $metadata[$entityName];
$tableName = $mapping->table;
$fields = array();
$indexes = array();
foreach($mapping->newProperties AS $propertyName => $property) {
if($property instanceof Zend_Entity_Definition_RelationAbstract) {
if($property->inverse == false) {
$fieldName = $property->columnName;
$indexName = $fieldName."_fkey";
$fields[$fieldName] = new ezcDbSchemaField('integer', 10, !$property->nullable);
$indexes[$indexName] = new ezcDbSchemaIndex(array($fieldName => new ezcDbSchemaIndexField()), false, false);
}
} elseif($property instanceof Zend_Entity_Definition_Array) {
$arrayTableName = $property->table;
$arrayTableFields = array(
$property->key => new ezcDbSchemaField(
$mapping->primaryKey->propertyType,
$mapping->primaryKey->length,
false
),
$property->mapKey => new ezcDbSchemaField("text", 255, false),
$property->element => new ezcDbSchemaField("text", 255, false),
);
$arrayIndexes = array("primary" => new ezcDbSchemaIndex(
array(
$property->key => new ezcDbSchemaIndexField(),
$property->mapKey => new ezcDbSchemaIndexField()
),
true,
false
)
);
$tables[$arrayTableName] = new ezcDbSchemaTable($arrayTableFields, $arrayIndexes);
} elseif($property instanceof Zend_Entity_Definition_Collection) {
if($property->relation->inverse == false) {
$colTableName = $property->table;
if($colTableName != $tableName) {
$colFields = array(
$property->key => new ezcDbSchemaField('integer', 10, false),
$property->relation->columnName => new ezcDbSchemaField('integer', 10, false),
);
$colIndexes = array();
$colIndexes["primary"] = new ezcDbSchemaIndex(
array(
$property->key => new ezcDbSchemaIndexField(),
$property->relation->columnName => new ezcDbSchemaIndexField()
),
true,
false
);
// Special Unidirectional OneToMany table?
if($property->relation instanceof Zend_Entity_Definition_OneToMany) {
$colIndexes["onetomany_uniq"] = new ezcDbSchemaIndex(
array($property->relation->columnName => new ezcDbSchemaIndexField()), false, true
);
}
$tables[$colTableName] = new ezcDbSchemaTable($colFields, $colIndexes);
}
}
} elseif($property instanceof Zend_Entity_Definition_Property) {
$fieldName = $property->columnName;
$autoIncrement = false;
if($property === $mapping->primaryKey) {
$sequenceName = $tableName."_".$fieldName."_seq";
// wenn generator = native, ansonsten evtl andere sachen
$indexes[$sequenceName] = new ezcDbSchemaIndex(array($fieldName => new ezcDbSchemaIndexField()), true, false);
if($property->generator instanceof Zend_Entity_Definition_Id_AutoIncrement || $property->generator instanceof Zend_Entity_Definition_Id_Sequence) {
$autoIncrement = true;
}
} else if($property->isUnique()) {
$indexName = $fieldName."_idx";
$indexes[$indexName] = new ezcDbSchemaIndex(array($fieldName => new ezcDbSchemaIndexField()), false, true);
}
$type = $this->_types[$property->propertyType];
$fields[$fieldName] = new ezcDbSchemaField($type, $property->length, !$property->nullable, null, $autoIncrement);
}
}
$tables[$tableName] = new Whitewashing_DbSchema_Table($fields, $indexes);
}
// Avoid notice by setting the options
$options = new ezcDbSchemaOptions();
$options->tableNamePrefix = "";
ezcDbSchema::$options = $options;
$schema = new ezcDbSchema($tables);
$ddlGeneratorClassName = $this->_databasesDDLGenerators[$database];
$ddlGenerator = new $ddlGeneratorClassName;
/* @var $ddlGenerator ezcDbSchemaDbWriter */
$ddl = $ddlGenerator->convertToDDL($schema);
echo implode(";\n\n", $ddl)."\n";
return $ddl;
}
}
class Whitewashing_DbSchema_Table extends ezcDbSchemaTable
{
/**
* Constructs an ezcDbSchemaTable object.
*
* We do not want to sort the fields and indexes.
*
* @param array(string=>ezcDbSchemaField) $fields
* @param array(string=>ezcDbSchemaIndex) $indexes
*/
function __construct( $fields, $indexes = array() )
{
$this->fields = $fields;
$this->indexes = $indexes;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment