OBJ.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  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: #REF
  112. # TODO: update #REF should update #VERSION
  113. # TODO: #REF sctruct hould have #VERIFIED fields for both sides of relation - eg. change instance of some obj may break #REF from another obj
  114. # NOTE use UTC_TIMESTAMP() for #VERSION - better for sync @see http://billauer.co.il/blog/2009/03/mysql-datetime-epoch-unix-time/
  115. ```sql
  116. CREATE TABLE `TEST_USER` (
  117. `ID` int(11) NOT NULL,
  118. `LOGIN` varchar(20) NOT NULL,
  119. `PASSWORD` varchar(32) NOT NULL,
  120. `NAME` varchar(64) NOT NULL
  121. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  122. CREATE TABLE `TEST_USER__#CURRENT` (
  123. `#VERSION` int(10) UNSIGNED NOT NULL,
  124. `#PRIMARY_KEY` int(10) UNSIGNED NOT NULL,
  125. `#INSTANCE` varchar(100) NOT NULL DEFAULT '',
  126. `LOGIN` int(11) NOT NULL,
  127. `PASSWORD` int(11) NOT NULL,
  128. `NAME` int(11) NOT NULL,
  129. UNIQUE KEY `PRIMARY_KEY` (`#PRIMARY_KEY`)
  130. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  131. CREATE TABLE `TEST_USER__#FIELD__LOGIN` (
  132. `ID` int(11) NOT NULL AUTO_INCREMENT,
  133. `PRIMARY_KEY` int(11) NOT NULL,
  134. `VALUE` varchar(20) NOT NULL,
  135. PRIMARY KEY (`ID`), KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
  136. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  137. CREATE TABLE `TEST_USER__#FIELD__PASSWORD` (
  138. `ID` int(11) NOT NULL AUTO_INCREMENT,
  139. `PRIMARY_KEY` int(11) NOT NULL,
  140. `VALUE` varchar(32) NOT NULL,
  141. PRIMARY KEY (`ID`), KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
  142. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  143. CREATE TABLE `TEST_USER__#FIELD__NAME` (
  144. `ID` int(11) NOT NULL AUTO_INCREMENT,
  145. `PRIMARY_KEY` int(11) NOT NULL,
  146. `VALUE` varchar(64) NOT NULL,
  147. PRIMARY KEY (`ID`), KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
  148. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  149. CREATE TABLE `TEST_USER__#LOG` (
  150. `ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  151. `#GLOBAL_LOG_ID` bigint UNSIGNED DEFAULT NULL,
  152. `#PRIMARY_KEY` int(10) UNSIGNED NOT NULL,
  153. `#INSTANCE` varchar(100) NOT NULL DEFAULT '',
  154. `LOGIN` int(11) NOT NULL,
  155. `PASSWORD` int(11) NOT NULL,
  156. `NAME` int(11) NOT NULL,
  157. PRIMARY KEY (`ID`),
  158. KEY `PRIMARY_KEY` (`#PRIMARY_KEY`)
  159. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  160. ```
  161. */
  162. class OBJ {
  163. public static function getName($json) {
  164. if (empty($json['name'])) throw new Exception("Struct error - name not defined in " . json_encode($json));
  165. return (is_array($json['name']))? end($json['name']) : $json['name'];
  166. }
  167. public static function getLabel($json) {
  168. if (empty($json['label'])) return null;
  169. return (is_array($json['label']))? end($json['label']) : $json['label'];
  170. }
  171. // @returns array of parent object names
  172. public static function getParentList($json) {
  173. if (empty($json['parent_object'])) return array();
  174. return (!is_array($json['parent_object']))? array($json['parent_object']) : array_reverse($json['parent_object']);
  175. }
  176. public static function getFields($json) {
  177. if (empty($json['fields'])) throw new Exception("Struct error - object has no fields");
  178. return $json['fields'];
  179. }
  180. public static function getTableFields($json) {
  181. if (empty($json['fields'])) throw new Exception("Struct error - object has no fields");
  182. $fields = array();
  183. foreach ($json['fields'] as $fldName => $fldConf) {
  184. switch ($fldConf['type']) {
  185. case 'int': $fields[] = $fldName; break;
  186. case 'string': $fields[] = $fldName; break;
  187. // TODO: more field types
  188. }
  189. }
  190. return $fields;
  191. }
  192. public static function getStorageName($json) {
  193. if (empty($json['db_source'])) throw new Exception("Struct error - object has no source defined");
  194. return $json['db_source'];
  195. }
  196. public static function getMainTableName($json) {
  197. if (empty($json['db_table'])) throw new Exception("Struct error - object has no table name defined");
  198. return $json['db_table'];
  199. }
  200. public static function getPrimaryKeyType($json) {
  201. // [keys] => Array(
  202. // [PRIMARY] => Array(
  203. // [fields] => ID
  204. // [auto_increment] => 1
  205. if (empty($json['keys'])) throw new Exception("Struct error - object has no keys defined");
  206. if (empty($json['keys']['PRIMARY'])) throw new Exception("Struct error - object has no PRIMARY key defined");
  207. if (empty($json['keys']['PRIMARY']['fields'])) throw new Exception("Struct error - object PRIMARY key has no fields defined");
  208. if (is_array($json['keys']['PRIMARY']['fields'])) throw new Exception("Not implemented - multiple fields primary key");
  209. $primaryKey = $json['keys']['PRIMARY']['fields'];
  210. if (empty($json['fields'][$primaryKey])) throw new Exception("Struct error - object priary key field not defined in fields list");
  211. $type = V::get('type', '', $json['fields'][$primaryKey]);
  212. if (empty($type)) throw new Exception("Struct error - object primary field type not defined");
  213. if ('int' != $type) throw new Exception("Not implemented - primary key field type is no int");
  214. return $type;
  215. }
  216. public static function getCoreObjectFromFile($objectName) {
  217. $objectFileName = str_replace("/", '-', $objectName);
  218. $filePath = APP_PATH_SCHEMA . "/gui/core/{$objectFileName}.json";
  219. if (!file_exists($filePath)) throw new Exception("File not exists {$filePath}", 404);
  220. $json = file_get_contents($filePath);
  221. DBG::_('DBG', '>1', "{$objectName} filePath", $filePath, __CLASS__, __FUNCTION__, __LINE__);
  222. DBG::_('DBG', '>1', "{$objectName} file content", $json, __CLASS__, __FUNCTION__, __LINE__);
  223. $json = @json_decode($json, $assoc = true);
  224. DBG::_('DBG', '>1', "{$objectName} json_last_error()", json_last_error(), __CLASS__, __FUNCTION__, __LINE__);
  225. if (null == $json && 0 !== json_last_error()) throw new Exception("Parse json error for object '{$objectName}': " . json_last_error());
  226. if (empty($json['parent_object'])) return $json;
  227. $jsonParent = array();
  228. $parent = (is_array($json['parent_object']))? end($json['parent_object']) : $json['parent_object'];
  229. $jsonParent = self::getCoreObjectFromFile($parent);
  230. return array_merge_recursive($jsonParent, $json);
  231. }
  232. public static function getCoreObjectList() {
  233. $objectList = array();
  234. $files = glob(APP_PATH_SCHEMA . "/gui/core/*.json", GLOB_NOSORT);
  235. //DBG::_(true, true, "files", $files, __CLASS__, __FUNCTION__, __LINE__);
  236. foreach ($files as $filePath) {
  237. $fileName = basename($filePath);
  238. $objName = substr($fileName, 0, -5);// remove ext '.json'
  239. $objectList[] = $objName;
  240. }
  241. return $objectList;
  242. }
  243. public static function checkInstall($json) {
  244. self::checkInstanceTable($json);
  245. self::checkRefTables($json);
  246. self::checkActivityLogTable($json);
  247. }
  248. public static function checkInstanceTable($json) {
  249. $mainTableName = self::getMainTableName($json);
  250. $instanceTableName = "{$mainTableName}__INSTANCE_CLOSURE";
  251. $primaryKeyType = "int(11)";// TODO: fetch from main table - default int(11)
  252. $storageName = self::getStorageName($json);
  253. $storagePdo = DB::getStorage($storageName);
  254. try {
  255. $mainTableStruct = $storagePdo->getTableStruct($mainTableName);
  256. } catch (Exception $e) {
  257. throw $e;
  258. // TODO: if (404 != $e->getCode()) -> CREATE BASE TABLE -- mv to TODO: checkMainTableInstall($json)
  259. }
  260. try {
  261. $instanceTableStruct = DB::getStorage()->getTableStruct($instanceTableName);
  262. } catch (Exception $e) {
  263. if (404 != $e->getCode()) throw $e;
  264. $instanceTableStruct = null;
  265. }
  266. $sqlCreate = "
  267. CREATE TABLE IF NOT EXISTS `{$instanceTableName}` (
  268. `PRIMARY_KEY` {$primaryKeyType} NOT NULL,
  269. `INSTANCE` varchar(124) NOT NULL,
  270. `PARENT_INSTANCE` varchar(124) DEFAULT NULL,
  271. `PARENT_DEPTH` int(11) NOT NULL,
  272. KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
  273. ) ENGINE=MyISAM DEFAULT CHARSET=latin2
  274. ";
  275. DBG::_('DBG', '>2', "mainTableStruct", $mainTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  276. DBG::_('DBG', '>2', "instanceTableStruct", $instanceTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  277. DBG::_('DBG', '>2', "sqlCreate", $sqlCreate, __CLASS__, __FUNCTION__, __LINE__);
  278. if (!$instanceTableStruct) {
  279. DB::getPDO()->exec($sqlCreate);
  280. }
  281. try {
  282. $instanceTableStruct = DB::getStorage()->getTableStruct($instanceTableName);
  283. } catch (Exception $e) {
  284. throw new Exception("Wystąpiły błędy podczas tworzenie tabeli instancji dla {$mainTableName}");
  285. }
  286. DBG::_('DBG', '>2', "OK instance table exists - instanceTableStruct", $instanceTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  287. }
  288. public static function checkRefTables($json) {
  289. // TODO: should go recurse or create on demand? - create on demand
  290. $objectName = self::getName($json);
  291. $mainTableName = self::getMainTableName($json);
  292. $objectPrimaryKeyType = self::getPrimaryKeyType($json);
  293. if (empty($json['fields'])) return;
  294. $toCreateRefTables = array();// ref table name => target primary key type
  295. foreach ($json['fields'] as $fldName => $fld) {
  296. if ('ref' != V::get('type', '', $fld)) continue;
  297. // [ref_LOCAL_EMAIL] => Array(
  298. // [label] => Adresy email lokalnej poczty
  299. // [type] => ref
  300. // [ref_config] => Array(
  301. // [name] => user__ref__local_email
  302. // [target] => local_email
  303. $refConf = V::get('ref_config', '', $fld);
  304. if (!$refConf) throw new Exception("Struct error - ref config not defined for field {$objectName}/{$fldName}");
  305. $refTarget = V::get('target', '', $refConf);
  306. if (!$refConf) throw new Exception("Struct error - ref target not defined for field {$objectName}/{$fldName}");
  307. $jsonTarget = OBJ::getCoreObjectFromFile($refTarget);
  308. $targetMainTableName = self::getMainTableName($jsonTarget);
  309. $refTableName = "{$mainTableName}__REF__{$targetMainTableName}";
  310. $targetPrimaryKeyType = self::getPrimaryKeyType($jsonTarget);
  311. DBG::_('DBG', '>1', "create table `{$refTableName}` ( `PRIMARY_KEY` {$objectPrimaryKeyType}, `REMOTE_PRIMARY_KEY` {$targetPrimaryKeyType}) ", null, __CLASS__, __FUNCTION__, __LINE__);
  312. $toCreateRefTables[ $refTableName ] = $targetPrimaryKeyType;
  313. }
  314. foreach ($toCreateRefTables as $refTableName => $targetPrimaryKeyType) {
  315. // `{tbl_name}__REF__{target_table_name}`: `PRIMARY_KEY`, `REMOTE_PRIMARY_KEY`
  316. $sqlCreate = "
  317. CREATE TABLE IF NOT EXISTS `{$refTableName}` (
  318. `PRIMARY_KEY` {$objectPrimaryKeyType} NOT NULL,
  319. `REMOTE_PRIMARY_KEY` {$targetPrimaryKeyType} NOT NULL,
  320. KEY `PRIMARY_KEY` (`PRIMARY_KEY`),
  321. KEY `REMOTE_PRIMARY_KEY` (`REMOTE_PRIMARY_KEY`)
  322. ) ENGINE=MyISAM DEFAULT CHARSET=latin2
  323. ";
  324. DB::getPDO()->exec($sqlCreate);
  325. try {
  326. $refTableStruct = DB::getStorage()->getTableStruct($refTableName);
  327. } catch (Exception $e) {
  328. throw new Exception("Wystąpiły błędy podczas tworzenie tabeli ref {$refTableName}");
  329. }
  330. }
  331. }
  332. public static function checkActivityLogTable($json) {
  333. // `{tbl_name}__ACTIVITY_LOG`:
  334. // - `ID` int PRIMARY auto_increment - used in update to check conflicts
  335. // - `PRIMARY_KEY` - same type as root table primary key
  336. // - `ACTION_USER` varchar(20)
  337. // - `ACTION_DATE` datetime
  338. // - `ACTION_TYPE` enum('CREATE', 'UPDATE', 'DELETE')
  339. // - `LOG` text - json with action details
  340. // - `ERRORS` text - json with errors
  341. $mainTableName = self::getMainTableName($json);
  342. $histTableName = "{$mainTableName}__ACTIVITY_LOG";
  343. $primaryKeyType = self::getPrimaryKeyType($json);// default "int";
  344. $storageName = self::getStorageName($json);
  345. $storagePdo = DB::getStorage($storageName);
  346. $mainTableStruct = $storagePdo->getTableStruct($mainTableName);
  347. try {
  348. $histTableStruct = DB::getStorage()->getTableStruct($histTableName);
  349. } catch (Exception $e) {
  350. if (404 != $e->getCode()) throw $e;
  351. $histTableStruct = null;
  352. }
  353. $sqlCreate = "
  354. CREATE TABLE IF NOT EXISTS `{$histTableName}` (
  355. `ID` int(11) NOT NULL AUTO_INCREMENT,
  356. `PRIMARY_KEY` {$primaryKeyType} NOT NULL,
  357. `ACTION_USER` varchar(20) NOT NULL,
  358. `ACTION_DATE` datetime NOT NULL,
  359. `ACTION_TYPE` enum('CREATE','UPDATE','DELETE') NOT NULL,
  360. `LOG` text NOT NULL,
  361. `ERRORS` text NOT NULL,
  362. PRIMARY KEY (`ID`),
  363. KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
  364. ) ENGINE=MyISAM DEFAULT CHARSET=latin2
  365. ";
  366. DBG::_('DBG', '>2', "mainTableStruct", $mainTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  367. DBG::_('DBG', '>2', "instanceTableStruct", $histTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  368. DBG::_('DBG', '>2', "sqlCreate", $sqlCreate, __CLASS__, __FUNCTION__, __LINE__);
  369. if (!$histTableStruct) {
  370. DB::getPDO()->exec($sqlCreate);
  371. }
  372. try {
  373. $histTableStruct = DB::getStorage()->getTableStruct($histTableName);
  374. } catch (Exception $e) {
  375. throw new Exception("Wystąpiły błędy podczas tworzenie tabeli hist dla {$mainTableName}");
  376. }
  377. DBG::_('DBG', '>2', "OK hist table exists - histTableStruct", $histTableStruct, __CLASS__, __FUNCTION__, __LINE__);
  378. }
  379. public static function parseAll() {
  380. DBG::activate();
  381. $mapInheritance = array();
  382. $objList = self::getCoreObjectList();
  383. foreach ($objList as $objName) {
  384. $json = self::getCoreObjectFromFile($objName);
  385. $parentList = OBJ::getParentList($json);
  386. DBG::_(true, true, "obj({$objName}) parentList:", $parentList, __CLASS__, __FUNCTION__, __LINE__);
  387. if (!empty($parentList)) {
  388. /*
  389. obj(stanowisko) parentList = Array(
  390. [0] => group
  391. [1] => zasob
  392. [2] => default_db/crm_lista_zasobow
  393. */
  394. $rootTable = array_pop($parentList);
  395. if (!array_key_exists($rootTable, $mapInheritance)) $mapInheritance[$rootTable] = array();
  396. array_unshift($parentList, $objName);
  397. foreach ($parentList as $parentName) {
  398. if (!in_array($parentName, $mapInheritance[$rootTable])) $mapInheritance[$rootTable][] = $parentName;
  399. }
  400. }
  401. DBG::_(true, true, "mapInheritance:", $mapInheritance, __CLASS__, __FUNCTION__, __LINE__);
  402. }
  403. }
  404. }