24 protected $intMatch=
'@^.*?int.*?((?:\((?:\d)+\))*?)$@';
28 public function isInt($fieldType){
29 return \preg_match($this->intMatch, $fieldType);
32 $this->nameProtection=
"`";
33 $this->createDatabaseMask=
"CREATE DATABASE %name%";
34 $this->selectDbMask=
"USE %name%";
35 $this->createTableMask=
"CREATE TABLE %name% (%fields%) %attributes%";
36 $this->fieldMask=
"%name% %type% %extra%";
37 $this->alterTableMask=
"ALTER TABLE %tableName% %alter%";
38 $this->foreignKeyMask=
"ALTER TABLE %tableName% ADD CONSTRAINT %fkName% FOREIGN KEY (%fkFieldName%) REFERENCES %referencesTableName% (%referencesFieldName%) ON DELETE %onDelete% ON UPDATE %onUpdate%";
39 $this->alterTableAddKey=
"ALTER TABLE %tableName% ADD %type% KEY (%pkFields%)";
40 $this->autoIncMask=
"ALTER TABLE %tableName% MODIFY %field% AUTO_INCREMENT, AUTO_INCREMENT=%value%";
41 $this->fieldTypes=[
"tinyint"=>0,
"int"=>0,
"decimal"=>0,
"float"=>0,
"double"=>0,
"smallint"=>0,
"mediumint"=>0,
"bigint"=>0,
42 "date"=>
"NULL",
"time"=>
"NULL",
"datetime"=>
"CURRENT_TIMESTAMP",
"timestamp"=>
"CURRENT_TIMESTAMP",
"year"=>
"'0000'",
43 "tinytext"=>
"NULL",
"text"=>
"NULL",
"mediumtext"=>
"NULL",
"longtext"=>
"NULL",
44 "tinyblob"=>
"NULL",
"blob"=>
"NULL",
"mediumblob"=>
"NULL",
"longblob"=>
"NULL",
45 "char"=>
"NULL",
"varchar"=>
"NULL",
"binary"=>
"NULL",
"varbinary"=>
"NULL",
46 "enum"=>
"''",
"set"=>
"''" 48 $this->defaultType=
"varchar(30)";
52 $script= $this->
replaceMask(
"name", $name, $this->createDatabaseMask);
57 $script= $this->
replaceMask(
"name", $name, $this->selectDbMask);
61 public function createTable($name,$fieldsAttributes,$attributes=[
"ENGINE=InnoDB",
"DEFAULT CHARSET=utf8"]){
63 $attributes=\implode(
" ", $attributes);
64 $script=$this->
replaceArrayMask([
"name"=>$name,
"fields"=>$fields,
"attributes"=>$attributes], $this->createTableMask);
68 public function addKey($tableName,$fieldNames,$type=
"PRIMARY"){
70 foreach ($fieldNames as $fieldName){
71 $pks[]=$this->nameProtection.$fieldName.$this->nameProtection;
73 $script= $this->
replaceArrayMask([
"tableName"=>$tableName,
"pkFields"=>\implode(
",", $pks),
"type"=>$type], $this->alterTableAddKey);
74 return $this->
addScript(
"before-constraints", $script);
77 public function addForeignKey($tableName,$fkFieldName,$referencesTableName,$referencesFieldName,$fkName=null,$onDelete=
"CASCADE",$onUpdate=
"NO ACTION"){
81 $script= $this->
replaceArrayMask([
"tableName"=>$tableName,
"fkName"=>$fkName,
"fkFieldName"=>$fkFieldName,
"referencesTableName"=>$referencesTableName,
"referencesFieldName"=>$referencesFieldName,
"onDelete"=>$onDelete,
"onUpdate"=>$onUpdate], $this->foreignKeyMask);
82 return $this->
addScript(
"constraints", $script);
85 public function addAutoInc($tableName,$fieldName,$value=1){
86 $script= $this->
replaceArrayMask([
"tableName"=>$tableName,
"field"=>$fieldName,
"value"=>$value], $this->autoIncMask);
87 return $this->
addScript(
"before-constraints", $script);
91 if(!isset($this->sqlScript[$key])){
92 $this->sqlScript[$key]=[];
94 $this->sqlScript[$key][]=$script;
99 if(\array_search($name, $this->constraintNames)){
101 if (\preg_match(
'@([\s\S]*?)((?:\d)+)$@', $name,$matches)) {
102 if(isset($matches[2])){
103 $nb=\intval($matches[2])+1;
104 $name= $matches[1].$nb;
110 $this->constraintNames[]=$name;
120 $result=$fieldAttributes;
121 $type=$fieldAttributes[
"type"];
124 if (\preg_match($this->typeMatch, $type,$matches)) {
125 if(isset($matches[1])){
126 $strType=$matches[1];
127 if(isset($this->fieldTypes[$strType])){
128 if(!isset($fieldAttributes[
"extra"]) || $fieldAttributes[
"extra"]==
"") {
129 $result[
"extra"]=
"DEFAULT ".$this->fieldTypes[$strType];
143 foreach ($fieldsAttributes as $fieldAttribute){
146 return \implode(
",", $result);
150 if(\strstr(\strtolower($key),
"name"))
151 $value=$this->nameProtection.$value.$this->nameProtection;
152 return \str_replace(
"%".$key.
"%", $value, $mask);
156 foreach ($keyValues as $key=>$value){
167 if(!isset($this->manyToManys[$jointable])){
168 $this->manyToManys[$jointable]=[];
170 $this->manyToManys[$jointable][]=$targetEntity;
174 foreach ($this->manyToManys as $joinTable=>$targetEntities){
183 $invertedJoinColumns=[];
184 foreach ($targetEntities as $targetEntity){
187 $fieldName=$pk.\ucfirst($shortClassName);
188 $fields[]=$fieldName;
191 $memberName=\lcfirst($shortClassName);
192 $manyToOnes[]=$memberName;
193 $invertedJoinColumns[$fieldName]=[
"member"=>$memberName,
"className"=>$targetEntity];
195 $metas=[
"#tableName"=>$joinTable,
"#primaryKeys"=>$fields,
"#nullable"=>[],
196 "#notSerializable"=>[],
"#fieldTypes"=>
$fieldTypes,
"#manyToOne"=>$manyToOnes,
197 "#invertedJoinColumn"=>$invertedJoinColumns,
"#oneToMany"=>[],
"#joinTable"=>[],
198 "#manyToMany"=>[],
"#fieldNames"=>$fields
201 $tableGenerator->init($metas);
202 $tableGenerator->generateSQL($this);
206 $scripts=\array_merge($this->sqlScript[
"head"],$this->sqlScript[
"body"]);
207 $scripts=\array_merge($scripts,$this->sqlScript[
"before-constraints"]);
208 $scripts=\array_merge($scripts,$this->sqlScript[
"constraints"]);
209 return \implode(
";\n", $scripts);
generateField($fieldAttributes)
static getFieldType($className, $field)
generateManyToMany($joinTable, $targetEntities)
checkConstraintName($name)
static getFirstKey($class)
replaceMask($key, $value, $mask)
checkFieldAttributes($fieldAttributes)
addAutoInc($tableName, $fieldName, $value=1)
addForeignKey($tableName, $fkFieldName, $referencesTableName, $referencesFieldName, $fkName=null, $onDelete="CASCADE", $onUpdate="NO ACTION")
generateFields($fieldsAttributes)
addKey($tableName, $fieldNames, $type="PRIMARY")
addManyToMany($jointable, $targetEntity)
createTable($name, $fieldsAttributes, $attributes=["ENGINE=InnoDB","DEFAULT CHARSET=utf8"])
replaceArrayMask($keyValues, $mask)
static getClassSimpleName($classnameWithNamespace)