tableContructor.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <?php
  2. namespace MGModule\DNSManager2\mgLibs\models;
  3. use MGModule\DNSManager2 as main;
  4. /**
  5. * Description of tableContructor
  6. *
  7. * @author Michal Czech <michael@modulesgarden.com>
  8. */
  9. class tableContructor {
  10. private $prefix;
  11. private $engine = 'InnoDB';
  12. private $charset = 'UTF8';
  13. private $refrences = array();
  14. private $mainNameSpace = 'main';
  15. private $existsTables = array();
  16. private $declaredTables = array();
  17. static $predefinedColumTypes = array(
  18. 'id' => array(
  19. 'definition' => 'int(:int) AUTO_INCREMENT'
  20. ,'default' => array(
  21. 'int' => 11
  22. ,'isPrimaryKey' => true
  23. )
  24. )
  25. ,'varchar' => array(
  26. 'definition' => 'varchar(:varchar) CHARACTER SET :charset COLLATE :collation'
  27. ,'default' => array(
  28. 'varchar' => 128
  29. ,'charset' => 'utf8'
  30. )
  31. )
  32. ,'custom' => array(
  33. 'definition' => ':custom'
  34. )
  35. ,'mediumblob' => array(
  36. 'definition' => 'mediumblob'
  37. ,'default' => array(
  38. )
  39. )
  40. ,'smallint' => array(
  41. 'definition' => 'smallint(:smallint)'
  42. ,'default' => array(
  43. 'smallint' => 6
  44. )
  45. )
  46. ,'tinyint' => array(
  47. 'definition' => 'tinyint(:tinyint)'
  48. ,'default' => array(
  49. 'tinyint' => 6
  50. )
  51. )
  52. ,'boolean' => array(
  53. 'definition' => 'tinyint(:tinyint)'
  54. ,'default' => array(
  55. 'tinyint' => 1
  56. )
  57. )
  58. ,'datetime' => array(
  59. 'definition' => 'datetime DEFAULT :default'
  60. ,'default' => array(
  61. 'default' => 'NULL'
  62. )
  63. )
  64. ,'date' => array(
  65. 'definition' => 'date DEFAULT :default'
  66. ,'default' => array(
  67. 'default' => 'NULL'
  68. )
  69. )
  70. ,'int' => array(
  71. 'definition' => 'int(:int)'
  72. ,'default' => array(
  73. 'int' => 11
  74. )
  75. )
  76. ,'mediumtext' => array(
  77. 'definition' => 'mediumtext'
  78. ,'default' => array(
  79. )
  80. )
  81. ,'text' => array(
  82. 'definition' => 'text CHARACTER SET :charset COLLATE :collation'
  83. ,'default' => array(
  84. )
  85. )
  86. );
  87. function __construct($namespace,$prefix) {
  88. $this->mainNameSpace = $namespace;
  89. $this->prefix = $prefix;
  90. $result = main\mgLibs\MySQL\query::query("SHOW Tables");
  91. while($column = $result->fetchColumn())
  92. {
  93. $this->existsTables[] = $column;
  94. }
  95. }
  96. function createDBModels($models){
  97. foreach($models as $model)
  98. {
  99. $class = $this->mainNameSpace."\\".$model;
  100. if(!class_exists($class))
  101. {
  102. throw new main\mgLibs\exceptions\system('Model Class Not Exists');
  103. }
  104. $structure = $class::getTableStructure();
  105. $this->createTable($structure);
  106. }
  107. $this->createRefrences();
  108. }
  109. function createTable($structure)
  110. {
  111. $collationDetails = main\mgLibs\custom\helpers\CollationHelper::getCollation('tbldomainpricing');
  112. if(isset($structure['preventUpdate']))
  113. {
  114. return;
  115. }
  116. if(empty($structure['name']))
  117. {
  118. throw new main\mgLibs\exceptions\system('Table name is empty');
  119. }
  120. if(in_array($structure['name'], $this->declaredTables) && !isset($structure['multipleUsage']))
  121. {
  122. throw new main\mgLibs\exceptions\system('Table declared in other model');
  123. }
  124. $this->declaredTables[] = $structure['name'];
  125. $tableName = empty($structure['prefixed'])?$structure['name']:$this->prefix.$structure['name'];
  126. $charset = empty($structure['charset']) ? ($collationDetails['charset'] ? $collationDetails['charset'] : $this->charset) : $structure['charset'];
  127. $collation = empty($structure['collation']) ? ($collationDetails['collation'] ? $collationDetails['collation'] : 'utf8_general_ci') : 'utf8_general_ci';
  128. $engine = empty($structure['engine'])?$this->engine:$structure['engine'];
  129. $columns = array();
  130. $keys = array(
  131. 'keys' => array()
  132. ,'primary' => null
  133. );
  134. $existsColumns = array();
  135. $addNewColumns = array();
  136. $updateColumns = array();
  137. if(in_array($tableName, $this->existsTables))
  138. {
  139. $result = main\mgLibs\MySQL\query::query("SHOW COLUMNS IN `$tableName`");
  140. while($row = $result->fetch())
  141. {
  142. $existsColumns[$row['Field']] = $row;
  143. }
  144. }
  145. foreach($structure['columns'] as $column => $data)
  146. {
  147. $type = null;
  148. $options = array();
  149. foreach($data as $name => $value)
  150. {
  151. $options[] = "$name=$value";
  152. if(isset(self::$predefinedColumTypes[$name]))
  153. {
  154. $type = $name;
  155. }
  156. }
  157. if($type == null)
  158. {
  159. throw new main\mgLibs\exceptions\system('Unable to find provided column type: ('.implode(',',$options).')');
  160. }
  161. $config = self::$predefinedColumTypes[$type]['default'];
  162. $config['charset'] = $charset;
  163. $config['collation'] = $collation;
  164. if(in_array($type, array('varchar')))
  165. {
  166. main\mgLibs\custom\helpers\CollationHelper::setCollationForTableStructure($config, $collationDetails);
  167. }
  168. foreach($data as $name => $value)
  169. {
  170. if($value)
  171. {
  172. $config[$name] = $value;
  173. }
  174. }
  175. $definition = self::$predefinedColumTypes[$type]['definition'];
  176. $isNull = isset($config['null'])?$config['null']:false;
  177. $config['null'] = ($isNull)?'DEFAULT NULL':'NOT NULL';
  178. foreach($config as $name => $value)
  179. {
  180. $definition = str_replace(':'.$name, $value, $definition);
  181. }
  182. if(!empty($config['isPrimaryKey']))
  183. {
  184. $keys['primary'] = $config['name'];
  185. }
  186. if(!empty($config['isKey']))
  187. {
  188. $keys['keys'][] = $config['name'];
  189. }
  190. if(!empty($config['uniqueKey']))
  191. {
  192. $keys['uniqueKey'][] = $config['name'];
  193. }
  194. if(!empty($config['refrence']))
  195. {
  196. if(!isset($this->refrences[$tableName]))
  197. {
  198. $this->refrences[$tableName] = array();
  199. }
  200. $this->refrences[$tableName][] = array(
  201. 'column' => $config['name']
  202. ,'refrence' => $config['refrence']
  203. ,'ondelete' => (empty($config['ondelete']))?'CASCADE':$config['ondelete']
  204. ,'onupdate' => (empty($config['onupdate']))?'NO ACTION':$config['onupdate']
  205. );
  206. }
  207. if(isset($existsColumns[$config['name']]))
  208. {
  209. if(
  210. strpos($definition, $existsColumns[$config['name']]['Type']) === false
  211. || ($isNull && $existsColumns[$config['name']]['Type'] == 'YES')
  212. || (!$isNull && $existsColumns[$config['name']]['Type'] == 'NO')
  213. )
  214. {
  215. $updateColumns[$config['name']] = '`'.$config['name'].'` '.$definition;
  216. }
  217. }
  218. else
  219. {
  220. $addNewColumns[] = '`'.$config['name'].'` '.$definition;
  221. }
  222. }
  223. if(!in_array($tableName, $this->existsTables))
  224. {
  225. if(!empty($keys['primary']))
  226. {
  227. $addNewColumns[] = 'PRIMARY KEY (`'.$keys['primary'].'`)';
  228. }
  229. if(!empty($keys['keys']))
  230. {
  231. foreach($keys['keys'] as $key)
  232. {
  233. $addNewColumns[] = 'KEY `'.$key.'` (`'.$key.'`)';
  234. }
  235. }
  236. if(!empty($keys['uniqueKey']))
  237. {
  238. $addNewColumns[] = 'UNIQUE `unique'.implode('_',$keys['uniqueKey']).'` (`'.implode('`,`',$keys['uniqueKey']).'`)';
  239. }
  240. }
  241. if(in_array($tableName, $this->existsTables))
  242. {
  243. foreach($updateColumns as $column => $definition)
  244. {
  245. $sql = "ALTER TABLE `$tableName` CHANGE `$column` $definition";
  246. main\mgLibs\MySQL\query::query($sql);
  247. }
  248. foreach($addNewColumns as $definition)
  249. {
  250. $sql = "ALTER TABLE `$tableName` ADD $definition";
  251. main\mgLibs\MySQL\query::query($sql);
  252. }
  253. }
  254. else
  255. {
  256. $sql = 'CREATE TABLE `'.$tableName.'` (';
  257. $sql .= implode(",\n",$addNewColumns);
  258. $sql .= ') ENGINE='.$engine.' DEFAULT CHARSET='.$charset
  259. .($collationDetails['collation'] ? ' COLLATE='.$collationDetails['collation'] : '');
  260. main\mgLibs\MySQL\query::query($sql);
  261. }
  262. }
  263. function createRefrences(){
  264. foreach ($this->refrences as $table => $refrences)
  265. {
  266. $result = main\mgLibs\MySQL\query::query("
  267. SHOW CREATE TABLE `".$table."`");
  268. $row = $result->fetch();
  269. $struct = $row['Create Table'];
  270. foreach($refrences as $id => $refrence)
  271. {
  272. $refName = $table.'_ibfk_'.($id+1);
  273. $column = $refrence['column'];
  274. list($model,$refProperty) = explode('::',$refrence['refrence']);
  275. $class = $this->mainNameSpace."\\".$model;
  276. $refColumn = $class::getProperyColumn($refProperty);
  277. $refTable = $class::tableName();
  278. if(strpos($struct, $refName))
  279. {
  280. $sql = "
  281. ALTER TABLE
  282. `".$table."`
  283. DROP FOREIGN KEY `$refName`;";
  284. main\mgLibs\MySQL\query::query($sql);
  285. }
  286. $sql = "ALTER TABLE
  287. `$table`
  288. ADD CONSTRAINT
  289. `$refName`
  290. FOREIGN KEY
  291. (`$column`)
  292. REFERENCES
  293. `$refTable` (`$refColumn`)
  294. ON DELETE ".$refrence['ondelete']."
  295. ON UPDATE ".$refrence['onupdate']." ;
  296. ";
  297. main\mgLibs\MySQL\query::query($sql);
  298. }
  299. }
  300. }
  301. function dropModels($models){
  302. foreach($models as $model)
  303. {
  304. $class = $this->mainNameSpace."\\".$model;
  305. $structure = $class::getTableStructure();
  306. $sql = "select COLUMN_NAME, CONSTRAINT_NAME, REFERENCED_COLUMN_NAME, REFERENCED_TABLE_NAME
  307. from information_schema.KEY_COLUMN_USAGE
  308. where TABLE_NAME = 'table to be checked';";
  309. }
  310. }
  311. }