AclReinstall.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. <?php
  2. Lib::loadClass('RouteBase');
  3. Lib::loadClass('Router');
  4. Lib::loadClass('Response');
  5. Lib::loadClass('UI');
  6. Lib::loadClass('SchemaFactory');
  7. Lib::loadClass('RefConfig');
  8. Lib::loadClass('Type_Field');
  9. class Route_Storage_AclReinstall extends RouteBase {
  10. public function handleAuth() {
  11. if (!User::logged()) {
  12. User::authByRequest();
  13. }
  14. }
  15. public function defaultAction() {
  16. UI::gora();
  17. UI::startContainer();
  18. try {
  19. $namespace = V::get('namespace', '', $_GET);
  20. if (empty($namespace)) throw new Exception("Missing param namespace");
  21. echo UI::h('h3', [], $namespace);
  22. echo UI::h('p', [], [
  23. UI::h('a', [
  24. 'href' => Router::getRoute('Storage_AclStruct')->getLink('', [ 'namespace' => $namespace ]),
  25. 'class' => "btn btn-md btn-link",
  26. ], "<i class=\"glyphicon glyphicon-arrow-left\"></i> Wróć do struktury"),
  27. " | ",
  28. UI::h('a', [
  29. 'href' => $this->getLink('viewXsdSource', [ 'namespace' => $namespace ]),
  30. 'class' => "btn btn-md btn-link",
  31. 'target' => "_blank",
  32. ], "Otwórz plik xsd (źródłowy)"),
  33. ]);
  34. if ('reinstall' == V::get('_postTask', '', $_POST)) {
  35. $this->reinstallAcl($namespace);
  36. return;
  37. }
  38. echo UI::hButtonPost("Reinstall", [
  39. 'data' => [
  40. '_postTask' => 'reinstall'
  41. ],
  42. 'class' => 'btn btn-md btn-danger',
  43. 'title' => "Reinstall structure"
  44. ]);
  45. echo '<hr>';
  46. try {
  47. $this->printReinstallPreview($namespace);
  48. } catch (Exception $e) {
  49. DBG::log($e);
  50. UI::alert('danger', $e->getMessage());
  51. }
  52. } catch (Exception $e) {
  53. UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  54. DBG::log($e);
  55. }
  56. UI::endContainer();
  57. UI::dol();
  58. }
  59. public function printReinstallPreview($namespace) {
  60. $objectItem = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => "*,field" ]);
  61. DBG::log($objectItem, 'array', '$objectItem preview');
  62. switch ($objectItem['_type']) {
  63. case 'AntAcl': $this->printReinstallAntAclPreview($objectItem); break;
  64. case 'TableAcl': $this->printReinstallTableAclPreview($objectItem); break;
  65. case 'StorageAcl': $this->printReinstallStorageAclPreview($objectItem); break;
  66. default: throw new Exception("TODO: Not Implemented type '{$objectItem['_type']}'");
  67. }
  68. }
  69. public function printReinstallAntAclPreview($item) {
  70. Lib::loadClass('Schema_SystemObjectFieldStorageAcl');
  71. $antAclPath = Schema_SystemObjectFieldStorageAcl::getAntAclXsdBasePath($item['typeName']);
  72. if (!file_exists("{$antAclPath}/build.xml")) throw new Exception("Ant build file not exists " . str_replace(APP_PATH_ROOT, 'SE', $antAclPath));
  73. Lib::loadClass('XML');
  74. $xsdType = XML::getXsdTypeFromXsdSchema("{$antAclPath}/{$item['name']}.xsd", $namespace = $item['namespace'], $name = $item['name']);
  75. DBG::nicePrint($item, '$item');
  76. $sortPrio = 0;
  77. foreach ($xsdType['struct'] as $fieldName => $fieldItem) {
  78. $xsdType['struct'][$fieldName]['sortPrio'] = $sortPrio++;
  79. }
  80. DBG::nicePrint($xsdType, '$xsdType');
  81. // TODO: fix sortPrio for all fields if not set = 0
  82. echo '<hr>';
  83. echo UI::h('h3', [], "Lista zmian:");
  84. echo ($item['primaryKey'] != $xsdType['primaryKey'])
  85. ? UI::h('p', [ 'style' => "" ], "@primaryKey - zmiana z '{$item['primaryKey']}' na '{$xsdType['primaryKey']}'")
  86. : UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "@primaryKey - bez zmian");
  87. if (empty($xsdType['struct'])) throw new Exception("Field list not found for '{$item['namespace']}'");
  88. foreach ($xsdType['struct'] as $fieldName => $x) {
  89. $listEnum = [];
  90. if (!empty($x['restrictions']['enumeration'])) {
  91. $listEnum = $x['restrictions']['enumeration'];
  92. unset($x['restrictions']['enumeration']);
  93. }
  94. if (!empty($listEnum)) {
  95. DBG::log($listEnum, 'array', "\$listEnum for field '{$fieldName}'");
  96. }
  97. }
  98. $old = [
  99. 'fields' => array_map(function ($field) { return $field['fieldNamespace']; }, $item['field']),
  100. ];
  101. $new = [
  102. 'fields' => array_keys($xsdType['struct']),
  103. ];
  104. sort($old['fields']);
  105. sort($new['fields']);
  106. $diffFieldsToCreate = array_diff($new['fields'], $old['fields']);
  107. $diffFieldsToRemove = array_diff($old['fields'], $new['fields']);
  108. $sameFields = array_intersect($new['fields'], $old['fields']);
  109. echo (!empty($diffFieldsToCreate))
  110. ? UI::h('details', [ 'open' => "open" ], [
  111. UI::h('summary', [], "Pola do dodania (".count($diffFieldsToCreate)."):"),
  112. UI::h('ul', [], array_map(function ($fieldName) {
  113. return UI::h('li', [], $fieldName);
  114. }, $diffFieldsToCreate)),
  115. ])
  116. : UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Brak pól do dodania");
  117. echo (!empty($diffFieldsToRemove))
  118. ? UI::h('details', [ 'open' => "open", 'style' => "margin:4px 0; color:#8a6d3b; background-color:#fcf8e3; border:1px solid #faebcc;" ], [
  119. UI::h('summary', [ 'style' => "padding:4px; outline:none; cursor:pointer" ], "Pola do usunięcia (".count($diffFieldsToRemove)."):"),
  120. UI::h('ul', [], array_map(function ($fieldName) {
  121. return UI::h('li', [], $fieldName);
  122. }, $diffFieldsToRemove)),
  123. ])
  124. : UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Brak pól do usunięcia");
  125. foreach ($sameFields as $fieldName) {
  126. // UI::alert('warning', "TODO: is field changed? '{$fieldName}'");
  127. $oldField = array_filter($item['field'], function ($field) use ($fieldName) { return ( $fieldName === $field['fieldNamespace'] ); });
  128. $oldField = ($oldField) ? reset($oldField) : null;
  129. // DBG::nicePrint($oldField, "\$oldField '$fieldName'");
  130. $newField = $xsdType['struct'][$fieldName];
  131. // DBG::nicePrint($newField, "\$newField '$fieldName'");
  132. $fieldDiff = [];
  133. if ($newField['type'] !== $oldField['xsdType']) $fieldDiff[] = 'xsdType';
  134. if ($newField['minOccurs'] != $oldField['minOccurs']) $fieldDiff[] = 'minOccurs';
  135. if ($newField['maxOccurs'] != $oldField['maxOccurs']) $fieldDiff[] = 'maxOccurs';
  136. if (json_encode($newField['restrictions']) !== $oldField['xsdRestrictions']) $fieldDiff[] = 'xsdRestrictions';
  137. if (json_encode($newField['appInfo']) !== $oldField['appInfo']) $fieldDiff[] = 'appInfo';
  138. if (RefConfig::isRefField($item['namespace'], $fieldName)) {
  139. $typeNewField = Type_Field::build($newField);
  140. $typeOldField = Type_Field::build($oldField);
  141. if (RefConfig::needUpdate($item['namespace'], $oldField['fieldNamespace'], $typeNewField, $typeOldField)) {
  142. $fieldDiff[] = 'RefConfig';
  143. }
  144. }
  145. echo (!empty($fieldDiff))
  146. ? UI::h('p', [ 'style' => "" ], "Pole '{$fieldName}' - zmiany: " . implode(", ", $fieldDiff))
  147. : UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Pole '{$fieldName}' - bez zmian");
  148. }
  149. }
  150. public function printReinstallTableAclPreview($item) {
  151. throw new Exception("TODO: Podgląd zmian dla tabeli {$item['namespace']} ...");
  152. }
  153. public function printReinstallStorageAclPreview($item) {
  154. DBG::nicePrint($item, '$item');
  155. $acl = SchemaFactory::loadDefaultObject($item['name']);
  156. DBG::nicePrint($acl, '$acl');
  157. $xsdType = [
  158. 'primaryKey' => $acl->getPrimaryKeyField(),
  159. 'struct' => $acl->getFieldsWithXsdTypes()
  160. ];
  161. DBG::nicePrint($xsdType, '$xsdType');
  162. echo '<hr>';
  163. echo UI::h('h3', [], "Lista zmian:");
  164. echo ($item['primaryKey'] != $xsdType['primaryKey'])
  165. ? UI::h('p', [ 'style' => "" ], "@primaryKey - zmiana z '{$item['primaryKey']}' na '{$xsdType['primaryKey']}'")
  166. : UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "@primaryKey - bez zmian");
  167. if (empty($xsdType['struct'])) throw new Exception("Field list not found for '{$item['namespace']}'");
  168. foreach ($xsdType['struct'] as $fieldName => $x) {
  169. $listEnum = [];
  170. if (!empty($x['restrictions']['enumeration'])) {
  171. $listEnum = $x['restrictions']['enumeration'];
  172. unset($x['restrictions']['enumeration']);
  173. }
  174. if (!empty($listEnum)) {
  175. DBG::log($listEnum, 'array', "\$listEnum for field '{$fieldName}'");
  176. }
  177. }
  178. $old = [
  179. 'fields' => array_map(function ($field) { return $field['fieldNamespace']; }, $item['field']),
  180. ];
  181. $new = [
  182. 'fields' => array_keys($xsdType['struct']),
  183. ];
  184. sort($old['fields']);
  185. sort($new['fields']);
  186. $diffFieldsToCreate = array_diff($new['fields'], $old['fields']);
  187. $diffFieldsToRemove = array_diff($old['fields'], $new['fields']);
  188. $sameFields = array_intersect($new['fields'], $old['fields']);
  189. echo (!empty($diffFieldsToCreate))
  190. ? UI::h('details', [ 'open' => "open" ], [
  191. UI::h('summary', [], "Pola do dodania (".count($diffFieldsToCreate)."):"),
  192. UI::h('ul', [], array_map(function ($fieldName) {
  193. return UI::h('li', [], $fieldName);
  194. }, $diffFieldsToCreate)),
  195. ])
  196. : UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Brak pól do dodania");
  197. echo (!empty($diffFieldsToRemove))
  198. ? UI::h('details', [ 'open' => "open", 'style' => "margin:4px 0; color:#8a6d3b; background-color:#fcf8e3; border:1px solid #faebcc;" ], [
  199. UI::h('summary', [ 'style' => "padding:4px; outline:none; cursor:pointer" ], "Pola do usunięcia (".count($diffFieldsToRemove)."):"),
  200. UI::h('ul', [], array_map(function ($fieldName) {
  201. return UI::h('li', [], $fieldName);
  202. }, $diffFieldsToRemove)),
  203. ])
  204. : UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Brak pól do usunięcia");
  205. foreach ($sameFields as $fieldName) {
  206. // UI::alert('warning', "TODO: is field changed? '{$fieldName}'");
  207. $oldField = array_filter($item['field'], function ($field) use ($fieldName) { return ( $fieldName === $field['fieldNamespace'] ); });
  208. $oldField = ($oldField) ? reset($oldField) : null;
  209. // DBG::nicePrint($oldField, "\$oldField '$fieldName'");
  210. $newField = $xsdType['struct'][$fieldName];
  211. // DBG::nicePrint($newField, "\$newField '$fieldName'");
  212. $fieldDiff = [];
  213. if ($newField['type'] !== $oldField['xsdType']) $fieldDiff[] = 'xsdType';
  214. if ($newField['minOccurs'] != $oldField['minOccurs']) $fieldDiff[] = 'minOccurs';
  215. if ($newField['maxOccurs'] != $oldField['maxOccurs']) $fieldDiff[] = 'maxOccurs';
  216. if (json_encode($newField['restrictions']) !== $oldField['xsdRestrictions']) $fieldDiff[] = 'xsdRestrictions';
  217. if (json_encode($newField['appInfo']) !== $oldField['appInfo']) $fieldDiff[] = 'appInfo';
  218. echo (!empty($fieldDiff))
  219. ? UI::h('p', [ 'style' => "" ], "Pole '{$fieldName}' - zmiany: " . implode(", ", $fieldDiff))
  220. : UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Pole '{$fieldName}' - bez zmian");
  221. }
  222. }
  223. public function viewXsdSourceAction() {
  224. try {
  225. $namespace = V::get('namespace', '', $_GET);
  226. if (empty($namespace)) throw new Exception("Missing param namespace");
  227. $objectItem = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => "*,field" ]);
  228. switch ($objectItem['_type']) {
  229. case 'AntAcl': $this->viewXsdSource($objectItem); break;
  230. // case 'TableAcl': $this->viewXsdSource($objectItem); break;
  231. default: throw new Exception("TODO: Not Implemented type '{$objectItem['_type']}'");
  232. }
  233. } catch (Exception $e) {
  234. DBG::log($e);
  235. echo "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage();
  236. }
  237. }
  238. function viewXsdSource($objectItem) {
  239. if (empty($objectItem)) throw new Exception("Missing objectItem in viewXsdSource");
  240. DBG::log($objectItem, "viewXsdSource \$objectItem");
  241. Lib::loadClass('Schema_SystemObjectFieldStorageAcl');
  242. $antAclPath = Schema_SystemObjectFieldStorageAcl::getAntAclXsdBasePath($objectItem['typeName']);
  243. if (!file_exists("{$antAclPath}/build.xml")) throw new Exception("Ant build file not exists");
  244. DBG::log(str_replace(APP_PATH_ROOT, '~', $antAclPath), "viewXsdSource \$antAclPath");
  245. $xsdFile = "{$antAclPath}/{$objectItem['name']}.xsd";
  246. if (!file_exists($xsdFile)) throw new Exception("Xsd file not exists");
  247. DBG::log(str_replace(APP_PATH_ROOT, '~', $xsdFile), "viewXsdSource \$xsdFile");
  248. header('Content-Type: application/xml; charset=utf-8');
  249. $fd = fopen($xsdFile, 'r');
  250. fpassthru($fd);
  251. exit;
  252. }
  253. function reinstallAcl($namespace) {
  254. try {
  255. $this->_createOrUpdateTableStructure($namespace);
  256. } catch (Exception $e) {
  257. DBG::log($e);
  258. UI::alert('danger', $e->getMessage());
  259. }
  260. Lib::loadClass('Schema_SystemObjectFieldStorageAcl');
  261. $objFieldAcl = new Schema_SystemObjectFieldStorageAcl();
  262. $objFieldAcl->updateCache($namespace);
  263. try {
  264. $dbgInfo = [
  265. 'idInstance' => ACL::getInstanceId($namespace),
  266. // 'rootInstance' => InstanceConfig::getRootNamespace($namespace),
  267. // 'conf' => InstanceConfig::fetchInstanceConfig($namespace),
  268. ];
  269. DBG::nicePrint($dbgInfo, "dbg");
  270. } catch (Exception $e) {
  271. DBG::log($e);
  272. UI::alert('warning', $e->getMessage());
  273. }
  274. $childRefList = RefConfig::getChildRefFullList($namespace);
  275. DBG::nicePrint($childRefList, '$childRefList');
  276. DBG::nicePrint($item, '$item');
  277. $activeFields = array_filter($item['field'], function ($field) {
  278. return ($field['isActive'] > 0);
  279. });
  280. $fieldNsList = array_map(function ($field) {
  281. return $field['fieldNamespace'];
  282. }, $activeFields);
  283. DBG::nicePrint($fieldNsList, '$fieldNsList');
  284. if ('AntAcl' === $item['_type']) { // fix ref config status (turn on/off)
  285. foreach ($childRefList as $refConfig) { // [ namespace, A_STATUS ]
  286. if ($refConfig->status !== 'DELETED' && !in_array($refConfig->childName, $fieldNsList)) {
  287. UI::alert('danger', "remove ref config for '{$refConfig->childName}' ...");
  288. if (!$refConfig->id) throw new Exception("Missing ref config ID");
  289. RefConfig::remove($refConfig);
  290. }
  291. else if ($refConfig->status !== 'DELETED' && in_array($refConfig->childName, $fieldNsList)) {
  292. UI::alert('info', "ref config for '{$refConfig->childName}' active - OK");
  293. }
  294. else if ($refConfig->status === 'DELETED' && in_array($refConfig->childName, $fieldNsList)) {
  295. UI::alert('warning', "activate ref config for '{$refConfig->childName}' ...");
  296. if (!$refConfig->id) throw new Exception("Missing ref config ID");
  297. RefConfig::reactivate($refConfig);
  298. }
  299. else if ($refConfig->status === 'DELETED' && !in_array($refConfig->childName, $fieldNsList)) {
  300. UI::alert('info', "ref config for '{$refConfig->childName}' removed - OK");
  301. }
  302. else {
  303. UI::alert('danger', "Not implemented action for '{$refConfig->childName}'");
  304. }
  305. }
  306. // TODO: create missing refConfig - field is not in $childRefList
  307. }
  308. if ('AntAcl' === $item['_type']) { // fix ref tables by appInfo
  309. $activeRefFields = array_filter($item['field'], function ($field) {
  310. return ($field['isActive'] && 'ref:' === substr($field['xsdType'], 0, 4));
  311. });
  312. DBG::log($activeRefFields, 'array', "DBG \$activeRefFields");
  313. foreach ($activeRefFields as $field) {
  314. $typeNewField = Type_Field::build($field);
  315. // if (RefConfig::needUpdate($item['namespace'], $oldField['fieldNamespace'], $typeNewField, $typeOldField))
  316. try {
  317. RefConfig::update($item['namespace'], $field['fieldNamespace'], $typeNewField);
  318. } catch (Exception $e) {
  319. // TODO: deactivate RefConfig if error
  320. DBG::log($e);
  321. UI::alert('danger', $e->getMessage());
  322. }
  323. }
  324. }
  325. { // TODO: RMME? function is too slow for join query
  326. if ('AntAcl' === $item['_type']) {
  327. $idInstance = ACL::getInstanceId($namespace);
  328. $dbName = DB::getPDO()->getDatabaseName();
  329. DB::getPDO()->execSql(" DROP FUNCTION IF EXISTS `{$dbName}`.`isInstance_{$idInstance}` ");
  330. }
  331. }
  332. { // TODO: mv to updateCache
  333. if ('AntAcl' === $item['_type']) {
  334. $instConf = InstanceConfig::getInstanceConfig($namespace);
  335. InstanceConfig::createInstanceTable($instConf, $item); // force create instance table event if A_STATUS is NORMAL
  336. }
  337. }
  338. }
  339. function _createOrUpdateTableStructure($namespace) {
  340. $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
  341. DBG::nicePrint($item, 'DBG:_createOrUpdateTableStructure:$item');
  342. $storagePdo = DB::getStorage($item['idDatabase']);
  343. $tblStruct = [];
  344. try {
  345. $tblStruct = $storagePdo->getTableStruct($item['_rootTableName']);
  346. } catch (Exception $e) {
  347. }
  348. DBG::nicePrint($tblStruct, 'DBG:_createOrUpdateTableStructure:$tblStruct');
  349. if (DB::getPDO()->getZasobId() != $item['idDatabase']) throw new Exception("Not imeplemented Create/Update table structure in non default database");
  350. if (empty($tblStruct)) $this->_createTableStructure($item);
  351. else $this->_updateTableStructure($item, $tblStruct);
  352. }
  353. // $item['idDatabase'] => int idDatabase
  354. // $item['_rootTableName'] => string tableName
  355. // $item['primaryKey'] => string primaryKey fieldName
  356. // $item['field'] => []
  357. // $item['field']['fieldNamespace'] => fieldName,
  358. // $item['field']['xsdRestrictions'] => [] // TODO: handle restrictions like maxLength, etc.
  359. // $item['field']['xsdType'] `select distinct xsdType from `CRM_#CACHE_ACL_OBJECT_FIELD` where xsdType not like 'ref:%'`: [
  360. // default_db__x3A__BADANIA_W_TERENIE:A_STATUS_Type
  361. // default_db__x3A__CRM_PROCES:TYPE_Simple
  362. // gml:AbstractFeatureType
  363. // gml:PolygonPropertyType
  364. // p5:enum
  365. // p5:price
  366. // p5:www_link
  367. // p5Type:date
  368. // p5Type:dateTime
  369. // p5Type:decimal
  370. // p5Type:integer
  371. // p5Type:lineString
  372. // p5Type:point
  373. // p5Type:polygon
  374. // p5Type:string
  375. // p5Type:text
  376. // xsd:date
  377. // xsd:dateTime
  378. // xsd:decimal
  379. // xsd:double
  380. // xsd:float
  381. // xsd:gYear
  382. // xsd:hexBinary
  383. // xsd:int
  384. // xsd:integer
  385. // xsd:long
  386. // xsd:positiveInteger
  387. // xsd:short
  388. // xsd:string
  389. // xsd:time
  390. // xsd:token
  391. // ]
  392. function _createTableStructure($item) {
  393. $tryConvertFields = array_map(function ($fieldInfo) {
  394. if ('ref:' === substr($fieldInfo['xsdType'], 0, 4)) return "Skipped create ref field '{$fieldInfo['xsdType']}'";
  395. switch ($fieldInfo['xsdType']) {
  396. case 'xsd:integer':
  397. case 'p5Type:integer':
  398. case 'xsd:positiveInteger':
  399. case 'xsd:int': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "int(11)" ];
  400. case 'xsd:float': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "float" ];
  401. case 'xsd:double': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "double" ];
  402. case 'xsd:date': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "date" ];
  403. case 'xsd:datetime': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "datetime" ];
  404. case 'xsd:string':
  405. case 'p5Type:string': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "varchar(255)" ];
  406. // TODO: implement more xsd types:
  407. // case 'p5Type:decimal':
  408. // case 'xsd:decimal': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "decimal" ];
  409. // default_db__x3A__BADANIA_W_TERENIE:A_STATUS_Type
  410. // default_db__x3A__CRM_PROCES:TYPE_Simple
  411. // gml:AbstractFeatureType
  412. // gml:PolygonPropertyType
  413. // p5:enum
  414. // p5:price
  415. // p5:www_link
  416. // p5Type:date
  417. // p5Type:dateTime
  418. // p5Type:decimal
  419. // p5Type:lineString
  420. // p5Type:point
  421. // p5Type:polygon
  422. // p5Type:text
  423. // xsd:decimal
  424. // xsd:gYear
  425. // xsd:hexBinary
  426. // xsd:long
  427. // xsd:short
  428. // xsd:time
  429. // xsd:token
  430. default: return "Not implemented type '{$fieldInfo['xsdType']}'";
  431. }
  432. }, $item['field']);
  433. DBG::nicePrint($tryConvertFields, "DBG:create table struct:\$tryConvertFields");
  434. $toCreateFields = array_filter($tryConvertFields, function ($fieldInfo) { return is_array($fieldInfo); });
  435. DBG::nicePrint($toCreateFields, "DBG:create table struct:\$toCreateFields");
  436. $tblStruct = array_combine(
  437. array_map(V::makePick('name'), $toCreateFields),
  438. array_values($toCreateFields)
  439. );
  440. DBG::nicePrint($tblStruct, "DBG:create table struct:\$tblStruct");
  441. if (!array_key_exists($item['primaryKey'], $tblStruct)) throw new Exception("BUG: primaryKey field definition not exists");
  442. $tblStruct[$item['primaryKey']]['extra'] = "auto_increment";
  443. DB::getStorage($item['idDatabase'])->createTableStructure([
  444. 'tableName' => $item['_rootTableName'],
  445. 'fields' => $tblStruct,
  446. 'primaryKey' => $item['primaryKey'],
  447. 'keys' => [],
  448. ]);
  449. }
  450. function _updateTableStructure($item, $tblStruct) {
  451. throw new Exception("Not imeplemented Update table structure in non default database");
  452. }
  453. }