|
|
@@ -1,68 +1,22 @@
|
|
|
<?php
|
|
|
|
|
|
Lib::loadClass('SchemaVersionUpgrade');
|
|
|
+Lib::loadClass('Type_InstanceConfig');
|
|
|
+Lib::loadClass('SchemaFactory');
|
|
|
|
|
|
class InstanceConfig {
|
|
|
|
|
|
- static function createInstanceConfigTable() {
|
|
|
- DB::getPDO()->execSql("
|
|
|
- create table if not exists `CRM_INSTANCE_CONFIG` (
|
|
|
- `id` int(11) not null AUTO_INCREMENT,
|
|
|
- `namespace` varchar(255) NOT NULL DEFAULT '',
|
|
|
- `rootNamespace` varchar(255) NOT NULL DEFAULT '',
|
|
|
- `idInstanceBase` int(11) NOT NULL DEFAULT 0,
|
|
|
- `_createdAt` datetime NOT NULL,
|
|
|
- UNIQUE KEY `namespace` (`namespace`),
|
|
|
- KEY `rootNamespace` (`rootNamespace`),
|
|
|
- PRIMARY KEY (`id`)
|
|
|
- ) ENGINE=MyISAM DEFAULT CHARSET=latin2
|
|
|
- ");
|
|
|
- }
|
|
|
-
|
|
|
- static function getInstanceTable($namespace) { // @returns tableName with struct { pk, idInstance, _createdAt }
|
|
|
- $conf = self::getInstanceConfig($namespace);
|
|
|
- if (!empty($conf['idInstanceBase'])) return "CRM__#INSTANCE_TABLE__{$conf['idInstanceBase']}";
|
|
|
-
|
|
|
- $rootNs = $conf['rootNamespace'];
|
|
|
- $rootConf = self::getInstanceConfig($rootNs);
|
|
|
- $instanceTableName = "CRM__#INSTANCE_TABLE__{$rootConf['id']}";
|
|
|
- if (!empty($rootConf['idInstance'])) {
|
|
|
- $affected = DB::getPDO()->update("CRM_INSTANCE_CONFIG", 'rootNamespace', $rootNs, [
|
|
|
- 'idInstanceBase' => $rootConf['id']
|
|
|
- ]);
|
|
|
- return $instanceTableName;
|
|
|
- }
|
|
|
-
|
|
|
- // TODO: fetch primaryKeyType - TODO: store primaryKey and primaryKeyType in SystemObject item
|
|
|
- $pkType = 'int';
|
|
|
- DB::getPDO()->exec("
|
|
|
- CREATE TABLE IF NOT EXISTS `{$instanceTableName}` (
|
|
|
- `pk` int(11) NOT NULL COMMENT 'primary key'
|
|
|
- , `idInstance` int(11) NOT NULL
|
|
|
- , `_createdAt` datetime NOT NULL
|
|
|
- , KEY `pk` (`pk`)
|
|
|
- , KEY `idInstance` (`idInstance`)
|
|
|
- ) ENGINE=MyISAM DEFAULT CHARSET=latin2 COMMENT='{$rootNs} #INSTANCE';
|
|
|
- ");
|
|
|
- $affected = DB::getPDO()->update("CRM_INSTANCE_CONFIG", 'rootNamespace', $rootNs, [
|
|
|
- 'idInstanceBase' => $rootConf['id']
|
|
|
- ]);
|
|
|
- return $instanceTableName;
|
|
|
+ static function getInstanceTable($namespace) { // @return string - tableName with struct { pk, idInstance, _createdAt }
|
|
|
+ return self::getInstanceConfig($namespace)->tableName;
|
|
|
}
|
|
|
|
|
|
- static function getInstanceId($namespace) {
|
|
|
- return self::getInstanceConfig($namespace)['id'];
|
|
|
+ static function getInstanceId($namespace) { // @return int
|
|
|
+ return self::getInstanceConfig($namespace)->id;
|
|
|
}
|
|
|
|
|
|
- static function getInstanceConfig($namespace) { // @returns { id, namespace, rootNamespace, idInstanceBase, _createdAt }
|
|
|
+ static function getInstanceConfig($namespace) { // @return Type_InstanceConfig or throw Exception
|
|
|
SchemaVersionUpgrade::upgradeSchema();
|
|
|
- try {
|
|
|
- $conf = self::fetchInstanceConfig($namespace);
|
|
|
- } catch (Exception $e) {
|
|
|
- self::createInstanceConfigTable();
|
|
|
- // TODO:?: `_tableInstalled` tinyint(1) not null default 0,
|
|
|
- $conf = self::fetchInstanceConfig($namespace);
|
|
|
- }
|
|
|
+ $conf = self::fetchInstanceConfig($namespace);
|
|
|
if (!$conf) {
|
|
|
$id = DB::getPDO()->insert("CRM_INSTANCE_CONFIG", [
|
|
|
'namespace' => $namespace,
|
|
|
@@ -72,17 +26,83 @@ class InstanceConfig {
|
|
|
$conf = self::fetchInstanceConfig($namespace);
|
|
|
}
|
|
|
if (!$conf) throw new Exception("Instance not found in config table '{$namespace}'");
|
|
|
+
|
|
|
+ if ('NORMAL' !== $conf->status) {
|
|
|
+ try {
|
|
|
+ $objectItem = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
|
|
|
+ } catch (Exception $e) {
|
|
|
+ throw new Exception("Object not installed '{$namespace}'");
|
|
|
+ }
|
|
|
+ $conf = self::createInstanceTable($conf, $objectItem);
|
|
|
+ }
|
|
|
+
|
|
|
return $conf;
|
|
|
}
|
|
|
|
|
|
- static function fetchInstanceConfig($namespace) {
|
|
|
- return DB::getPDO()->fetchFirst("
|
|
|
+ static function fetchInstanceConfig($namespace) { // @return Type_InstanceConfig | null
|
|
|
+ $instanceRow = DB::getPDO()->fetchFirst("
|
|
|
select c.*
|
|
|
from `CRM_INSTANCE_CONFIG` c
|
|
|
where c.namespace = :namespace
|
|
|
", [
|
|
|
':namespace' => $namespace
|
|
|
]);
|
|
|
+ return ($instanceRow) ? Type_InstanceConfig::build($instanceRow) : null;
|
|
|
+ }
|
|
|
+
|
|
|
+ static function createInstanceTable(Type_InstanceConfig $conf, $objectItem) {
|
|
|
+ switch ($objectItem['instanceTableSource']) {
|
|
|
+ case 'table': {
|
|
|
+ self::_createInstanceTable($conf, $objectItem);
|
|
|
+ DB::getPDO()->update('CRM_INSTANCE_CONFIG', 'ID', $conf->id, [
|
|
|
+ 'A_STATUS' => "NORMAL",
|
|
|
+ 'version' => 1,
|
|
|
+ 'source' => "table"
|
|
|
+ ]);
|
|
|
+ return self::fetchInstanceConfig($conf->namespace);
|
|
|
+ }
|
|
|
+ case 'view': {
|
|
|
+ self::_createInstanceView($conf, $objectItem);
|
|
|
+ DB::getPDO()->update('CRM_INSTANCE_CONFIG', 'ID', $conf->id, [
|
|
|
+ 'A_STATUS' => "NORMAL",
|
|
|
+ 'version' => 1,
|
|
|
+ 'source' => "view"
|
|
|
+ ]);
|
|
|
+ return self::fetchInstanceConfig($conf->namespace);
|
|
|
+ }
|
|
|
+ default: {
|
|
|
+ DBG::log(['$objectItem'=>$objectItem, '$conf'=>$conf], 'array', "Not implemented instance table source type '{$objectItem['instanceTableSource']}'");
|
|
|
+ throw new Exception("Not implemented instance table source type '{$objectItem['instanceTableSource']}'");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return self::fetchInstanceConfig($conf->namespace);
|
|
|
+ }
|
|
|
+ static function _createInstanceTable(Type_InstanceConfig $conf, $objectItem) {
|
|
|
+ $instanceTableName = "CRM__#INSTANCE_TABLE__{$conf->id}";
|
|
|
+ // // TODO: fetch primaryKeyType - TODO: store primaryKey and primaryKeyType in SystemObject item
|
|
|
+ // $pkType = 'int';
|
|
|
+ DB::getPDO()->exec("
|
|
|
+ CREATE TABLE IF NOT EXISTS `{$instanceTableName}` (
|
|
|
+ `pk` int(11) NOT NULL COMMENT 'primary key'
|
|
|
+ , `idInstance` int(11) NOT NULL
|
|
|
+ , `_createdAt` datetime NOT NULL
|
|
|
+ , KEY `pk` (`pk`)
|
|
|
+ , KEY `idInstance` (`idInstance`)
|
|
|
+ ) ENGINE=MyISAM DEFAULT CHARSET=latin2 COMMENT='{$conf->namespace} #INSTANCE';
|
|
|
+ ");
|
|
|
+ // TODO: add author, idTransaction?, convert to EventSourcing
|
|
|
+ $affected = DB::getPDO()->update("CRM_INSTANCE_CONFIG", 'rootNamespace', $rootNs, [
|
|
|
+ 'SOURCE' => 'table',
|
|
|
+ 'VERSION' => 1,
|
|
|
+ ]);
|
|
|
+ // return $instanceTableName;
|
|
|
+ }
|
|
|
+ static function _createInstanceView(Type_InstanceConfig $conf, $objectItem) {
|
|
|
+ $idInstance = $conf->id;
|
|
|
+ $dbName = DB::getPDO()->getDatabaseName();
|
|
|
+ $sqlIsInstanceView = self::generateIsInstanceView($objectItem['namespace'], $objectItem, $conf);
|
|
|
+ DB::getPDO()->execSql(" DROP VIEW IF EXISTS `{$dbName}`.`CRM__#INSTANCE_TABLE__{$idInstance}_VIEW` ");
|
|
|
+ DB::getPDO()->execSql(" CREATE VIEW `{$dbName}`.`CRM__#INSTANCE_TABLE__{$idInstance}_VIEW` AS {$sqlIsInstanceView} ");
|
|
|
}
|
|
|
|
|
|
static function getRootNamespace($namespace) { // TODO: works only for relative urls! - mv to Acl->getRootNamespace
|
|
|
@@ -181,7 +201,7 @@ class InstanceConfig {
|
|
|
;
|
|
|
}
|
|
|
|
|
|
- static function generateIsInstanceFunctionBody($namespace, $item = null) {
|
|
|
+ static function generateIsInstanceFunctionBody($namespace, $item = null) { // TODO: NOT USED
|
|
|
if (!$item) $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
|
|
|
if (!in_array( $item['_type'], [ 'AntAcl' ] )) return null;
|
|
|
$localFieldsWithRestrictions = array_filter($item['field'], function ($field) {
|
|
|
@@ -207,10 +227,10 @@ class InstanceConfig {
|
|
|
return $sqlFunBody;
|
|
|
}
|
|
|
|
|
|
- static function generateIsInstanceView($namespace, $item = null) {
|
|
|
+ static function generateIsInstanceView($namespace, $item = null, Type_InstanceConfig $conf = null) {
|
|
|
if (!$item) $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
|
|
|
if (!in_array( $item['_type'], [ 'AntAcl' ] )) return null;
|
|
|
- $idInstance = self::getInstanceId($namespace);
|
|
|
+ $idInstance = ($conf) ? $conf->id : self::getInstanceId($namespace);
|
|
|
|
|
|
$localFieldsWithRestrictions = array_filter($item['field'], function ($field) {
|
|
|
if (!$field['isLocal']) return false;
|