OBJ.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?php
  2. // TODO: use char '#' in table name for system tables (instances, hist, ref's, etc.)
  3. /*
  4. * json files in schema/gui/core/
  5. * default_db-{tbl_name}.json - config for raw table - no 'parent_object' defined
  6. * {object_name}.json - config for object - require 'parent_object' (another object or default_db-* raw table object)
  7. # Instance table:
  8. `{tbl_name}__INSTANCE_CLOSURE`: `PRIMARY_KEY`, `INSTANCE`(przodek), `PARENT_INSTANCE`(przodek), `PARENT_DEPTH`(głębokość), , `_TS`
  9. TODO: closure tree http://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html
  10. ## sql - fetch rows with instance:
  11. ```sql
  12. select t.*
  13. , (select inst.INSTANCE
  14. from {tbl_name}__INSTANCE_CLOSURE inst
  15. where inst.PRIMARY_KEY = t.{primary_key}
  16. order by inst.PARENT_DEPTH DESC limit 1) as _instance
  17. from {tbl_name} t
  18. ```
  19. ## sql - fetch all
  20. ```sql
  21. select t.*
  22. from {tbl_name} t
  23. right join {tbl_name}__INSTANCE_CLOSURE inst on(t.{primary_key} = inst.PRIMARY_KEY)
  24. ```
  25. # Ref tables:
  26. `{tbl_name}__REF__{target_table_name}`: `PRIMARY_KEY`, `REMOTE_PRIMARY_KEY`, `ACCEPTED`, `_TS`
  27. ## sql - make ref connection
  28. ```sql
  29. insert into `{tbl_name}__REF__{target_table_name}` (`PRIMARY_KEY`, `REMOTE_PRIMARY_KEY`)
  30. -- TODO: save action to _HIST table
  31. ```
  32. # Hist table:
  33. `{tbl_name}__ACTIVITY_LOG`:
  34. - `ID` int PRIMARY auto_increment - used in update to check conflicts
  35. - `PRIMARY_KEY` - same type as root table primary key
  36. - `ACTION_USER` varchar(20)
  37. - `ACTION_DATE` datetime
  38. - `ACTION_TYPE` enum('CREATE', 'UPDATE', 'DELETE')
  39. - `LOG` text - json with action details
  40. - `ERRORS` text - json with errors
  41. # TODO: table names with '#':
  42. CREATE TABLE `CRM_FILES__#INSTANCE` - create files:
  43. CRM_FILES__@0023INSTANCE.MYD
  44. CRM_FILES__@0023INSTANCE.MYI
  45. CRM_FILES__@0023INSTANCE.frm
  46. # TODO: db API (only inserts => versioning, transactions):
  47. ## system table names:
  48. {baseTableName}__#CURRENT <- current version
  49. {baseTableName}__#LOG <- old versions
  50. {baseTableName}__#FIELD__{fieldName} <- values for field {fieldName}
  51. {baseTableName}__#INSTANCE_CLOSURE <- instance closure
  52. ### example structures for {baseTableName} = `test_user` (`ID`, `LOGIN`, `PASSWORD`, `NAME`)
  53. - {baseTableName}__#FIELD__LOGIN (ID BIGINT UNSIGNED auto_increment, PRIMARY_KEY, VALUE type same as in baseTable)
  54. - {baseTableName}__#FIELD__PASSWORD (ID BIGINT UNSIGNED auto_increment, PRIMARY_KEY, VALUE type same as in baseTable)
  55. - {baseTableName}__#FIELD__NAME (ID BIGINT UNSIGNED auto_increment, PRIMARY_KEY, VALUE type same as in baseTable)
  56. - {baseTableName}__#CURRENT:
  57. - `#VERSION`: BIGINT UNSIGNED -- current version from {baseTableName}__#LOG
  58. - `#PRIMARY_KEY`: BIGINT UNSIGNED (same as in {baseTable})
  59. - `#INSTANCE`: varchar(100) -- current instance name
  60. - `LOGIN`: BIGINT UNSIGNED -- id from {baseTableName}__#FIELD__LOGIN
  61. - `PASSWORD`: BIGINT UNSIGNED -- id from {baseTableName}__#FIELD__PASSWORD
  62. - `NAME`: BIGINT UNSIGNED -- id from {baseTableName}__#FIELD__NAME
  63. - ??? - `#REF__EMAIL_ALIAS`: BIGINT UNSIGNED
  64. - {baseTableName}__#LOG:
  65. - ...
  66. ## php API:
  67. ### php API - insert - `DB::getSchema('TEST_USER')->insert({LOGIN: 'test', PASSWORD: '1234...', NAME: 'Test user'});`:
  68. insert into `TEST_USER` (`LOGIN`, `PASSWORD`, `NAME`) values ('test', '1234...', 'Test User');
  69. # fetch last inserted id -> $pk - PRIMARY_KEY
  70. insert into `TEST_USER__#FIELD__LOGIN` (`PRIMARY_KEY`, `VALUE`) values ({$pk}, 'test'); // fetch last insert id -> $idFldLogin
  71. insert into `TEST_USER__#FIELD__PASSWORD` (`PRIMARY_KEY`, `VALUE`) values ({$pk}, '1234...'); // fetch last insert id -> $idFldPassword
  72. insert into `TEST_USER__#FIELD__NAME` (`PRIMARY_KEY`, `VALUE`) values ({$pk}, 'Test User'); // fetch last insert id -> $idFldName
  73. insert into `TEST_USER__#LOG` (`#PRIMARY_KEY`, `LOGIN`, `PASSWORD`, `NAME`) values ({$pk}, {$idFldLogin}, {$idFldPassword}, {$idFldName}); // fetch from last inserted id -> $version
  74. insert into `TEST_USER__#CURRENT` (`#VERSION`, `#PRIMARY_KEY`, `LOGIN`, `PASSWORD`, `NAME`)
  75. select ID as `#VERSION`
  76. , `#PRIMARY_KEY`
  77. , `LOGIN`
  78. , `PASSWORD`
  79. , `NAME`
  80. from `TEST_USER__#LOG`
  81. where ID = {$version};
  82. ### php API - update - `DB::getSchema('TEST_USER')->update($primary_key = 1, {PASSWORD: '9876...', NAME: 'Test Test'});`:
  83. PROCEDURE UPDATE ($pk, $lastVersion = NULL, $arg[LOGIN], $arg[PASSOWRD], $arg[NAME]):
  84. -- IF $lastVersion == NULL THEN -- dont check if current version is equal
  85. SET $changed = FALSE
  86. select t.`LOGIN`, t.`PASSWORD`, t.`NAME`
  87. , (select `VALUE` from `TEST_USER__#FIELD__LOGIN` where `ID`=t.`LOGIN`) as `val_LOGIN`
  88. , (select `VALUE` from `TEST_USER__#FIELD__PASSWORD` where `ID`=t.`PASSWORD`) as `val_PASSWORD`
  89. , (select `VALUE` from `TEST_USER__#FIELD__NAME` where `ID`=t.`NAME`) as `val_NAME`
  90. from `TEST_USER__#CURRENT` t where t.`#PRIMARY_KEY` = {$pk}
  91. into ($idFld[LOGIN], $idFld[PASSWORD], $idFld[NAME], $val[LOGIN], $val[PASSWORD], $val[NAME]);
  92. foreach fields as $fld:
  93. IF (select `VALUE` from `TEST_USER__#FIELD__{$fld}` where `PRIMARY_KEY`={$pk} order by ID DESC limit 1) != $arg[$fld] THEN
  94. insert into `TEST_USER__#FIELD__{$fld}` (`PRIMARY_KEY`, `VALUE`) values ({$pk}, $arg[$fld]);
  95. select LAST_INSERT_ID() into $idFld[$fld]
  96. SET $changed = TRUE
  97. IF $changed :
  98. -- insert into `#GLOBAL_LOG` -- last inserted id -> $idGlobalLog
  99. insert into `TEST_USER__#LOG` (`#PRIMARY_KEY`, `LOGIN`, `PASSWORD`, `NAME`)
  100. values ($pk, $idFld[LOGIN], $idFld[PASSWORD], $idFld[NAME]);
  101. select LAST_INSERT_ID() into $version
  102. update `TEST_USER__#CURRENT`
  103. set `#VERSION`=$version
  104. , `$fld` = $idFld[$fld] ...
  105. where `#PRIMARY_KEY` = $pk
  106. -- or more save with join -> move to procedure switch_version ($pk, $version)
  107. update `TEST_USER__#CURRENT` c, `TEST_USER__#LOG` l
  108. set c.`#VERSION` = l.`ID`
  109. , c.`{$fld}` - l.`{$fld}` ...
  110. where c.`#PRIMARY_KEY` = {$pk} and l.`ID` = {$version} and l.`#PRIMARY_KEY` = {$pk}
  111. # TODO: function to import data from _HIST table
  112. # TODO: #REF
  113. # TODO: update #REF should update #VERSION
  114. # TODO: #REF sctruct hould have #VERIFIED fields for both sides of relation - eg. change instance of some obj may break #REF from another obj
  115. # NOTE use UTC_TIMESTAMP() for #VERSION - better for sync @see http://billauer.co.il/blog/2009/03/mysql-datetime-epoch-unix-time/
  116. ```sql
  117. CREATE TABLE `TEST_USER` (
  118. `ID` int(11) NOT NULL,
  119. `LOGIN` varchar(20) NOT NULL,
  120. `PASSWORD` varchar(32) NOT NULL,
  121. `NAME` varchar(64) NOT NULL
  122. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  123. CREATE TABLE `TEST_USER__#CURRENT` (
  124. `#VERSION` int(10) UNSIGNED NOT NULL,
  125. `#PRIMARY_KEY` int(10) UNSIGNED NOT NULL,
  126. `#INSTANCE` varchar(100) NOT NULL DEFAULT '',
  127. `LOGIN` int(11) NOT NULL,
  128. `PASSWORD` int(11) NOT NULL,
  129. `NAME` int(11) NOT NULL,
  130. UNIQUE KEY `PRIMARY_KEY` (`#PRIMARY_KEY`)
  131. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  132. CREATE TABLE `TEST_USER__#FIELD__LOGIN` (
  133. `ID` int(11) NOT NULL AUTO_INCREMENT,
  134. `PRIMARY_KEY` int(11) NOT NULL,
  135. `VALUE` varchar(20) NOT NULL,
  136. PRIMARY KEY (`ID`), KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
  137. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  138. CREATE TABLE `TEST_USER__#FIELD__PASSWORD` (
  139. `ID` int(11) NOT NULL AUTO_INCREMENT,
  140. `PRIMARY_KEY` int(11) NOT NULL,
  141. `VALUE` varchar(32) NOT NULL,
  142. PRIMARY KEY (`ID`), KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
  143. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  144. CREATE TABLE `TEST_USER__#FIELD__NAME` (
  145. `ID` int(11) NOT NULL AUTO_INCREMENT,
  146. `PRIMARY_KEY` int(11) NOT NULL,
  147. `VALUE` varchar(64) NOT NULL,
  148. PRIMARY KEY (`ID`), KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
  149. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  150. CREATE TABLE `TEST_USER__#LOG` (
  151. `ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  152. `#GLOBAL_LOG_ID` bigint UNSIGNED DEFAULT NULL,
  153. `#PRIMARY_KEY` int(10) UNSIGNED NOT NULL,
  154. `#INSTANCE` varchar(100) NOT NULL DEFAULT '',
  155. `LOGIN` int(11) NOT NULL,
  156. `PASSWORD` int(11) NOT NULL,
  157. `NAME` int(11) NOT NULL,
  158. PRIMARY KEY (`ID`),
  159. KEY `PRIMARY_KEY` (`#PRIMARY_KEY`)
  160. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  161. ```
  162. */
  163. class OBJ {
  164. public static function getName($json) {
  165. if (empty($json['name'])) throw new Exception("Struct error - name not defined in " . json_encode($json));
  166. return (is_array($json['name']))? end($json['name']) : $json['name'];
  167. }
  168. public static function getLabel($json) {
  169. if (empty($json['label'])) return null;
  170. return (is_array($json['label']))? end($json['label']) : $json['label'];
  171. }
  172. // @returns array of parent object names
  173. public static function getParentList($json) {
  174. if (empty($json['parent_object'])) return array();
  175. return (!is_array($json['parent_object']))? array($json['parent_object']) : array_reverse($json['parent_object']);
  176. }
  177. public static function getFields($json) {
  178. if (empty($json['fields'])) throw new Exception("Struct error - object has no fields");
  179. return $json['fields'];
  180. }
  181. public static function getTableFields($json) {
  182. if (empty($json['fields'])) throw new Exception("Struct error - object has no fields");
  183. $fields = array();
  184. foreach ($json['fields'] as $fldName => $fldConf) {
  185. switch ($fldConf['type']) {
  186. case 'int': $fields[] = $fldName; break;
  187. case 'string': $fields[] = $fldName; break;
  188. // TODO: more field types
  189. }
  190. }
  191. return $fields;
  192. }
  193. public static function getStorageName($json) {
  194. if (empty($json['db_source'])) throw new Exception("Struct error - object has no source defined");
  195. return $json['db_source'];
  196. }
  197. public static function getMainTableName($json) {
  198. if (empty($json['db_table'])) throw new Exception("Struct error - object has no table name defined");
  199. return $json['db_table'];
  200. }
  201. public static function getPrimaryKeyType($json) {
  202. // [keys] => Array(
  203. // [PRIMARY] => Array(
  204. // [fields] => ID
  205. // [auto_increment] => 1
  206. if (empty($json['keys'])) throw new Exception("Struct error - object has no keys defined");
  207. if (empty($json['keys']['PRIMARY'])) throw new Exception("Struct error - object has no PRIMARY key defined");
  208. if (empty($json['keys']['PRIMARY']['fields'])) throw new Exception("Struct error - object PRIMARY key has no fields defined");
  209. if (is_array($json['keys']['PRIMARY']['fields'])) throw new Exception("Not implemented - multiple fields primary key");
  210. $primaryKey = $json['keys']['PRIMARY']['fields'];
  211. if (empty($json['fields'][$primaryKey])) throw new Exception("Struct error - object priary key field not defined in fields list");
  212. $type = V::get('type', '', $json['fields'][$primaryKey]);
  213. if (empty($type)) throw new Exception("Struct error - object primary field type not defined");
  214. if ('int' != $type) throw new Exception("Not implemented - primary key field type is no int");
  215. return $type;
  216. }
  217. public static function getCoreObjectFromFile($objectName) {
  218. $objectFileName = str_replace("/", '-', $objectName);
  219. $filePath = APP_PATH_SCHEMA . "/gui/core/{$objectFileName}.json";
  220. if (!file_exists($filePath)) throw new Exception("File not exists {$filePath}", 404);
  221. $json = file_get_contents($filePath);
  222. DBG::_('DBG', '>1', "{$objectName} filePath", $filePath, __CLASS__, __FUNCTION__, __LINE__);
  223. DBG::_('DBG', '>1', "{$objectName} file content", $json, __CLASS__, __FUNCTION__, __LINE__);
  224. $json = @json_decode($json, $assoc = true);
  225. DBG::_('DBG', '>1', "{$objectName} json_last_error()", json_last_error(), __CLASS__, __FUNCTION__, __LINE__);
  226. if (null == $json && 0 !== json_last_error()) throw new Exception("Parse json error for object '{$objectName}': " . json_last_error());
  227. if (empty($json['parent_object'])) return $json;
  228. $jsonParent = array();
  229. $parent = (is_array($json['parent_object']))? end($json['parent_object']) : $json['parent_object'];
  230. $jsonParent = self::getCoreObjectFromFile($parent);
  231. return array_merge_recursive($jsonParent, $json);
  232. }
  233. public static function getCoreObjectList() {
  234. $objectList = array();
  235. $files = glob(APP_PATH_SCHEMA . "/gui/core/*.json", GLOB_NOSORT);
  236. //DBG::_(true, true, "files", $files, __CLASS__, __FUNCTION__, __LINE__);
  237. foreach ($files as $filePath) {
  238. $fileName = basename($filePath);
  239. $objName = substr($fileName, 0, -5);// remove ext '.json'
  240. $objectList[] = $objName;
  241. }
  242. return $objectList;
  243. }
  244. public static function checkInstall($json) {
  245. self::checkInstanceTable($json);
  246. self::checkRefTables($json);
  247. self::checkActivityLogTable($json);
  248. }
  249. public static function checkInstanceTable($json) {
  250. $mainTableName = self::getMainTableName($json);
  251. $instanceTableName = "{$mainTableName}__INSTANCE_CLOSURE";
  252. $primaryKeyType = "int(11)";// TODO: fetch from main table - default int(11)
  253. $storageName = self::getStorageName($json);
  254. $storagePdo = DB::getStorage($storageName);
  255. try {
  256. $mainTableStruct = $storagePdo->getTableStruct($mainTableName);
  257. } catch (Exception $e) {
  258. throw $e;
  259. // TODO: if (404 != $e->getCode()) -> CREATE BASE TABLE -- mv to TODO: checkMainTableInstall($json)
  260. }
  261. try {
  262. $instanceTableStruct = DB::getStorage()->getTableStruct($instanceTableName);
  263. } catch (Exception $e) {
  264. if (404 != $e->getCode()) throw $e;
  265. $instanceTableStruct = null;
  266. }
  267. $sqlCreate = "
  268. CREATE TABLE IF NOT EXISTS `{$instanceTableName}` (
  269. `PRIMARY_KEY` {$primaryKeyType} NOT NULL,
  270. `INSTANCE` varchar(124) NOT NULL,
  271. `PARENT_INSTANCE` varchar(124) DEFAULT NULL,
  272. `PARENT_DEPTH` int(11) NOT NULL,
  273. KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
  274. ) ENGINE=MyISAM DEFAULT CHARSET=latin2
  275. ";
  276. DBG::_('DBG', '>2', "mainTableStruct", $mainTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  277. DBG::_('DBG', '>2', "instanceTableStruct", $instanceTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  278. DBG::_('DBG', '>2', "sqlCreate", $sqlCreate, __CLASS__, __FUNCTION__, __LINE__);
  279. if (!$instanceTableStruct) {
  280. DB::getPDO()->exec($sqlCreate);
  281. }
  282. try {
  283. $instanceTableStruct = DB::getStorage()->getTableStruct($instanceTableName);
  284. } catch (Exception $e) {
  285. throw new Exception("Wystąpiły błędy podczas tworzenie tabeli instancji dla {$mainTableName}");
  286. }
  287. DBG::_('DBG', '>2', "OK instance table exists - instanceTableStruct", $instanceTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  288. }
  289. public static function checkRefTables($json) {
  290. // TODO: should go recurse or create on demand? - create on demand
  291. $objectName = self::getName($json);
  292. $mainTableName = self::getMainTableName($json);
  293. $objectPrimaryKeyType = self::getPrimaryKeyType($json);
  294. if (empty($json['fields'])) return;
  295. $toCreateRefTables = array();// ref table name => target primary key type
  296. foreach ($json['fields'] as $fldName => $fld) {
  297. if ('ref' != V::get('type', '', $fld)) continue;
  298. // [ref_LOCAL_EMAIL] => Array(
  299. // [label] => Adresy email lokalnej poczty
  300. // [type] => ref
  301. // [ref_config] => Array(
  302. // [name] => user__ref__local_email
  303. // [target] => local_email
  304. $refConf = V::get('ref_config', '', $fld);
  305. if (!$refConf) throw new Exception("Struct error - ref config not defined for field {$objectName}/{$fldName}");
  306. $refTarget = V::get('target', '', $refConf);
  307. if (!$refConf) throw new Exception("Struct error - ref target not defined for field {$objectName}/{$fldName}");
  308. $jsonTarget = OBJ::getCoreObjectFromFile($refTarget);
  309. $targetMainTableName = self::getMainTableName($jsonTarget);
  310. $refTableName = "{$mainTableName}__REF__{$targetMainTableName}";
  311. $targetPrimaryKeyType = self::getPrimaryKeyType($jsonTarget);
  312. DBG::_('DBG', '>1', "create table `{$refTableName}` ( `PRIMARY_KEY` {$objectPrimaryKeyType}, `REMOTE_PRIMARY_KEY` {$targetPrimaryKeyType}) ", null, __CLASS__, __FUNCTION__, __LINE__);
  313. $toCreateRefTables[ $refTableName ] = $targetPrimaryKeyType;
  314. }
  315. foreach ($toCreateRefTables as $refTableName => $targetPrimaryKeyType) {
  316. // `{tbl_name}__REF__{target_table_name}`: `PRIMARY_KEY`, `REMOTE_PRIMARY_KEY`
  317. $sqlCreate = "
  318. CREATE TABLE IF NOT EXISTS `{$refTableName}` (
  319. `PRIMARY_KEY` {$objectPrimaryKeyType} NOT NULL,
  320. `REMOTE_PRIMARY_KEY` {$targetPrimaryKeyType} NOT NULL,
  321. KEY `PRIMARY_KEY` (`PRIMARY_KEY`),
  322. KEY `REMOTE_PRIMARY_KEY` (`REMOTE_PRIMARY_KEY`)
  323. ) ENGINE=MyISAM DEFAULT CHARSET=latin2
  324. ";
  325. DB::getPDO()->exec($sqlCreate);
  326. try {
  327. $refTableStruct = DB::getStorage()->getTableStruct($refTableName);
  328. } catch (Exception $e) {
  329. throw new Exception("Wystąpiły błędy podczas tworzenie tabeli ref {$refTableName}");
  330. }
  331. }
  332. }
  333. public static function checkActivityLogTable($json) {
  334. // `{tbl_name}__ACTIVITY_LOG`:
  335. // - `ID` int PRIMARY auto_increment - used in update to check conflicts
  336. // - `PRIMARY_KEY` - same type as root table primary key
  337. // - `ACTION_USER` varchar(20)
  338. // - `ACTION_DATE` datetime
  339. // - `ACTION_TYPE` enum('CREATE', 'UPDATE', 'DELETE')
  340. // - `LOG` text - json with action details
  341. // - `ERRORS` text - json with errors
  342. $mainTableName = self::getMainTableName($json);
  343. $histTableName = "{$mainTableName}__ACTIVITY_LOG";
  344. $primaryKeyType = self::getPrimaryKeyType($json);// default "int";
  345. $storageName = self::getStorageName($json);
  346. $storagePdo = DB::getStorage($storageName);
  347. $mainTableStruct = $storagePdo->getTableStruct($mainTableName);
  348. try {
  349. $histTableStruct = DB::getStorage()->getTableStruct($histTableName);
  350. } catch (Exception $e) {
  351. if (404 != $e->getCode()) throw $e;
  352. $histTableStruct = null;
  353. }
  354. $sqlCreate = "
  355. CREATE TABLE IF NOT EXISTS `{$histTableName}` (
  356. `ID` int(11) NOT NULL AUTO_INCREMENT,
  357. `PRIMARY_KEY` {$primaryKeyType} NOT NULL,
  358. `ACTION_USER` varchar(20) NOT NULL,
  359. `ACTION_DATE` datetime NOT NULL,
  360. `ACTION_TYPE` enum('CREATE','UPDATE','DELETE') NOT NULL,
  361. `LOG` text NOT NULL,
  362. `ERRORS` text NOT NULL,
  363. PRIMARY KEY (`ID`),
  364. KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
  365. ) ENGINE=MyISAM DEFAULT CHARSET=latin2
  366. ";
  367. DBG::_('DBG', '>2', "mainTableStruct", $mainTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  368. DBG::_('DBG', '>2', "instanceTableStruct", $histTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  369. DBG::_('DBG', '>2', "sqlCreate", $sqlCreate, __CLASS__, __FUNCTION__, __LINE__);
  370. if (!$histTableStruct) {
  371. DB::getPDO()->exec($sqlCreate);
  372. }
  373. try {
  374. $histTableStruct = DB::getStorage()->getTableStruct($histTableName);
  375. } catch (Exception $e) {
  376. throw new Exception("Wystąpiły błędy podczas tworzenie tabeli hist dla {$mainTableName}");
  377. }
  378. DBG::_('DBG', '>2', "OK hist table exists - histTableStruct", $histTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  379. }
  380. public static function parseAll() {
  381. DBG::activate();
  382. $mapInheritance = array();
  383. $objList = self::getCoreObjectList();
  384. foreach ($objList as $objName) {
  385. $json = self::getCoreObjectFromFile($objName);
  386. $parentList = OBJ::getParentList($json);
  387. DBG::_(true, true, "obj({$objName}) parentList:", $parentList, __CLASS__, __FUNCTION__, __LINE__);
  388. if (!empty($parentList)) {
  389. /*
  390. obj(stanowisko) parentList = Array(
  391. [0] => group
  392. [1] => zasob
  393. [2] => default_db/crm_lista_zasobow
  394. */
  395. $rootTable = array_pop($parentList);
  396. if (!array_key_exists($rootTable, $mapInheritance)) $mapInheritance[$rootTable] = array();
  397. array_unshift($parentList, $objName);
  398. foreach ($parentList as $parentName) {
  399. if (!in_array($parentName, $mapInheritance[$rootTable])) $mapInheritance[$rootTable][] = $parentName;
  400. }
  401. }
  402. DBG::_(true, true, "mapInheritance:", $mapInheritance, __CLASS__, __FUNCTION__, __LINE__);
  403. }
  404. }
  405. }