Piotr Labudda 9 лет назад
Родитель
Сommit
9685abe9dd
1 измененных файлов с 137 добавлено и 2 удалено
  1. 137 2
      SE/se-lib/OBJ.php

+ 137 - 2
SE/se-lib/OBJ.php

@@ -1,12 +1,14 @@
 <?php
 
+// TODO: use char '#' in table name for system tables (instances, hist, ref's, etc.)
+
 /*
  * json files in schema/gui/core/
  *   default_db-{tbl_name}.json - config for raw table - no 'parent_object' defined
  *   {object_name}.json - config for object - require 'parent_object' (another object or default_db-* raw table object)
 
 # Instance table:
-  `{tbl_name}__INSTANCE_CLOSURE`: `PRIMARY_KEY`, `INSTANCE`(przodek), `PARENT_INSTANCE`(przodek), `PARENT_DEPTH`(głębokość)
+  `{tbl_name}__INSTANCE_CLOSURE`: `PRIMARY_KEY`, `INSTANCE`(przodek), `PARENT_INSTANCE`(przodek), `PARENT_DEPTH`(głębokość), , `_TS`
 
 TODO: closure tree http://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html
 
@@ -28,7 +30,7 @@ TODO: closure tree http://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-q
 ```
 
 # Ref tables:
-  `{tbl_name}__REF__{target_table_name}`: `PRIMARY_KEY`, `REMOTE_PRIMARY_KEY`
+  `{tbl_name}__REF__{target_table_name}`: `PRIMARY_KEY`, `REMOTE_PRIMARY_KEY`, `ACCEPTED`, `_TS`
 
 ## sql - make ref connection
 ```sql
@@ -46,6 +48,139 @@ TODO: closure tree http://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-q
   - `LOG` text - json with action details
   - `ERRORS` text - json with errors
 
+# TODO: table names with '#':
+  CREATE TABLE `CRM_FILES__#INSTANCE` - create files:
+  	CRM_FILES__@0023INSTANCE.MYD
+  	CRM_FILES__@0023INSTANCE.MYI
+  	CRM_FILES__@0023INSTANCE.frm
+
+# TODO: db API (only inserts => versioning, transactions):
+## system table names:
+{baseTableName}__#CURRENT <- current version
+{baseTableName}__#LOG <- old versions
+{baseTableName}__#FIELD__{fieldName} <- values for field {fieldName}
+{baseTableName}__#INSTANCE_CLOSURE <- instance closure
+
+### example structures for {baseTableName} = `test_user` (`ID`, `LOGIN`, `PASSWORD`, `NAME`)
+- {baseTableName}__#FIELD__LOGIN    (ID BIGINT UNSIGNED auto_increment, PRIMARY_KEY, VALUE type same as in baseTable)
+- {baseTableName}__#FIELD__PASSWORD (ID BIGINT UNSIGNED auto_increment, PRIMARY_KEY, VALUE type same as in baseTable)
+- {baseTableName}__#FIELD__NAME     (ID BIGINT UNSIGNED auto_increment, PRIMARY_KEY, VALUE type same as in baseTable)
+- {baseTableName}__#CURRENT:
+  - `#VERSION`:     BIGINT UNSIGNED -- current version from {baseTableName}__#LOG
+  - `#PRIMARY_KEY`: BIGINT UNSIGNED (same as in {baseTable})
+  - `#INSTANCE`:    varchar(100) -- current instance name
+  - `LOGIN`:        BIGINT UNSIGNED -- id from {baseTableName}__#FIELD__LOGIN
+  - `PASSWORD`:     BIGINT UNSIGNED -- id from {baseTableName}__#FIELD__PASSWORD
+  - `NAME`:         BIGINT UNSIGNED -- id from {baseTableName}__#FIELD__NAME
+  - ??? - `#REF__EMAIL_ALIAS`: BIGINT UNSIGNED
+- {baseTableName}__#LOG:
+  - ...
+
+## php API:
+### php API - insert - `DB::getSchema('TEST_USER')->insert({LOGIN: 'test', PASSWORD: '1234...', NAME: 'Test user'});`:
+insert into `TEST_USER` (`LOGIN`, `PASSWORD`, `NAME`) values ('test', '1234...', 'Test User');
+# fetch last inserted id -> $pk - PRIMARY_KEY
+insert into `TEST_USER__#FIELD__LOGIN`    (`PRIMARY_KEY`, `VALUE`) values ({$pk}, 'test');      // fetch last insert id -> $idFldLogin
+insert into `TEST_USER__#FIELD__PASSWORD` (`PRIMARY_KEY`, `VALUE`) values ({$pk}, '1234...');   // fetch last insert id -> $idFldPassword
+insert into `TEST_USER__#FIELD__NAME`     (`PRIMARY_KEY`, `VALUE`) values ({$pk}, 'Test User'); // fetch last insert id -> $idFldName
+insert into `TEST_USER__#LOG` (`#PRIMARY_KEY`, `LOGIN`, `PASSWORD`, `NAME`) values ({$pk}, {$idFldLogin}, {$idFldPassword}, {$idFldName}); // fetch from last inserted id -> $version
+insert into `TEST_USER__#CURRENT` (`#VERSION`, `#PRIMARY_KEY`, `LOGIN`, `PASSWORD`, `NAME`)
+  select ID as `#VERSION`
+      , `#PRIMARY_KEY`
+      , `LOGIN`
+      , `PASSWORD`
+      , `NAME`
+  from `TEST_USER__#LOG`
+  where ID = {$version};
+
+### php API - update - `DB::getSchema('TEST_USER')->update($primary_key = 1, {PASSWORD: '9876...', NAME: 'Test Test'});`:
+PROCEDURE UPDATE ($pk, $lastVersion = NULL, $arg[LOGIN], $arg[PASSOWRD], $arg[NAME]):
+-- IF $lastVersion == NULL THEN -- dont check if current version is equal
+SET $changed = FALSE
+select t.`LOGIN`, t.`PASSWORD`, t.`NAME`
+    , (select `VALUE` from `TEST_USER__#FIELD__LOGIN`    where `ID`=t.`LOGIN`)    as `val_LOGIN`
+    , (select `VALUE` from `TEST_USER__#FIELD__PASSWORD` where `ID`=t.`PASSWORD`) as `val_PASSWORD`
+    , (select `VALUE` from `TEST_USER__#FIELD__NAME`     where `ID`=t.`NAME`)     as `val_NAME`
+  from `TEST_USER__#CURRENT` t where t.`#PRIMARY_KEY` = {$pk}
+  into ($idFld[LOGIN], $idFld[PASSWORD], $idFld[NAME], $val[LOGIN], $val[PASSWORD], $val[NAME]);
+foreach fields as $fld:
+  IF (select `VALUE` from `TEST_USER__#FIELD__{$fld}` where `PRIMARY_KEY`={$pk} order by ID DESC limit 1) != $arg[$fld] THEN
+    insert into `TEST_USER__#FIELD__{$fld}` (`PRIMARY_KEY`, `VALUE`) values ({$pk}, $arg[$fld]);
+    select LAST_INSERT_ID() into $idFld[$fld]
+    SET $changed = TRUE
+IF $changed :
+  -- insert into `#GLOBAL_LOG` -- last inserted id -> $idGlobalLog
+  insert into `TEST_USER__#LOG` (`#PRIMARY_KEY`, `LOGIN`, `PASSWORD`, `NAME`)
+    values ($pk, $idFld[LOGIN], $idFld[PASSWORD], $idFld[NAME]);
+  select LAST_INSERT_ID() into $version
+  update `TEST_USER__#CURRENT`
+    set `#VERSION`=$version
+      , `$fld` = $idFld[$fld] ...
+    where `#PRIMARY_KEY` = $pk
+  -- or more save with join -> move to procedure switch_version ($pk, $version)
+  update `TEST_USER__#CURRENT` c, `TEST_USER__#LOG` l
+    set c.`#VERSION` = l.`ID`
+      , c.`{$fld}` - l.`{$fld}` ...
+    where c.`#PRIMARY_KEY` = {$pk} and l.`ID` = {$version} and l.`#PRIMARY_KEY` = {$pk}
+
+# TODO: #REF
+  # TODO: update #REF should update #VERSION
+    # TODO: #REF sctruct hould have #VERIFIED fields for both sides of relation - eg. change instance of some obj may break #REF from another obj
+
+# NOTE use UTC_TIMESTAMP() for #VERSION - better for sync @see http://billauer.co.il/blog/2009/03/mysql-datetime-epoch-unix-time/
+
+```sql
+CREATE TABLE `TEST_USER` (
+  `ID` int(11) NOT NULL,
+  `LOGIN` varchar(20) NOT NULL,
+  `PASSWORD` varchar(32) NOT NULL,
+  `NAME` varchar(64) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE `TEST_USER__#CURRENT` (
+  `#VERSION` int(10) UNSIGNED NOT NULL,
+  `#PRIMARY_KEY` int(10) UNSIGNED NOT NULL,
+  `#INSTANCE` varchar(100) NOT NULL DEFAULT '',
+  `LOGIN` int(11) NOT NULL,
+  `PASSWORD` int(11) NOT NULL,
+  `NAME` int(11) NOT NULL,
+  UNIQUE KEY `PRIMARY_KEY` (`#PRIMARY_KEY`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE `TEST_USER__#FIELD__LOGIN` (
+  `ID` int(11) NOT NULL AUTO_INCREMENT,
+  `PRIMARY_KEY` int(11) NOT NULL,
+  `VALUE` varchar(20) NOT NULL,
+  PRIMARY KEY (`ID`), KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE `TEST_USER__#FIELD__PASSWORD` (
+  `ID` int(11) NOT NULL AUTO_INCREMENT,
+  `PRIMARY_KEY` int(11) NOT NULL,
+  `VALUE` varchar(32) NOT NULL,
+  PRIMARY KEY (`ID`), KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE `TEST_USER__#FIELD__NAME` (
+  `ID` int(11) NOT NULL AUTO_INCREMENT,
+  `PRIMARY_KEY` int(11) NOT NULL,
+  `VALUE` varchar(64) NOT NULL,
+  PRIMARY KEY (`ID`), KEY `PRIMARY_KEY` (`PRIMARY_KEY`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+CREATE TABLE `TEST_USER__#LOG` (
+  `ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `#GLOBAL_LOG_ID` bigint UNSIGNED DEFAULT NULL,
+  `#PRIMARY_KEY` int(10) UNSIGNED NOT NULL,
+  `#INSTANCE` varchar(100) NOT NULL DEFAULT '',
+  `LOGIN` int(11) NOT NULL,
+  `PASSWORD` int(11) NOT NULL,
+  `NAME` int(11) NOT NULL,
+  PRIMARY KEY (`ID`),
+  KEY `PRIMARY_KEY` (`#PRIMARY_KEY`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+```
+
  */
 class OBJ {