AsyncJobsDB.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <?php
  2. /**
  3. *
  4. `CRM_ASYNC_JOB_LOG`:
  5. `ID`
  6. `ID_FUNCTION`
  7. `ID_SOURCE_JOB`
  8. `P_ID`
  9. `DATE`
  10. `VERSION`
  11. `JOB_NAME`
  12. `LOCK_VALUE`
  13. `USER`
  14. `A_STATUS`
  15. `A_RECORD_CREATE_DATE`
  16. `A_RECORD_CREATE_AUTHOR`
  17. `A_RECORD_UPDATE_DATE`
  18. `A_RECORD_UPDATE_AUTHOR`
  19. *
  20. *
  21. */
  22. Lib::loadClass('Request');
  23. class Core_AsyncJobsDB {
  24. static $VERSION = 1; // `CRM_CONFIG`.`CONF_KEY` = 'Core_AsyncJobs__version'
  25. static $CRM_CONFIG_VERSION_KEY = 'Core_AsyncJobs__version';
  26. static function insert($item) {
  27. if (empty($item['JOB_NAME'])) throw new Exception("Missing JOB_NAME in Core_AsyncJobsDB::insert");
  28. return DB::getPDO()->insert('CRM_ASYNC_JOB_LOG', array_merge([
  29. 'ID_FUNCTION' => 0, // int(11) NOT NULL,
  30. // 'ID_SOURCE_JOB' int(11) NOT NULL DEFAULT 0, -- id job
  31. // 'P_ID' int(11) NOT NULL DEFAULT 0, -- parent job id
  32. 'DATE' => date("Y-m-d"),// date NOT NULL,
  33. // 'VERSION' => 0, // int(11) NOT NULL DEFAULT 0,
  34. 'JOB_NAME' => '', // varchar(200) NOT NULL, -- copy from CRM_ASYNC_FUNCTIONS
  35. 'LOCK_VALUE' => '', // varchar(200) NOT NULL DEFAULT '', -- second part for unique JOB_NAME eg. primaryKey
  36. 'USER' => User::getLogin(), // varchar(20) NOT NULL, -- user who start this function
  37. 'A_STATUS' => 'WAITING',
  38. 'A_RECORD_CREATE_DATE' => "NOW()",
  39. 'A_RECORD_CREATE_AUTHOR' => User::getLogin(),
  40. // UNIQUE KEY 'JOB_LOCK' ('JOB_NAME', 'LOCK_VALUE', 'USER'), -- add USER to store user click and respond that job is running by other user
  41. // KEY 'DATE' ('DATE'),
  42. // KEY 'A_STATUS' ('A_STATUS'),
  43. // KEY 'A_RECORD_UPDATE_DATE' ('A_RECORD_UPDATE_DATE')
  44. ], $item));
  45. }
  46. static function fetch($idJob) {
  47. return DB::getPDO()->fetchFirst("
  48. select j.*
  49. from CRM_ASYNC_JOB_LOG j
  50. where j.ID = :id
  51. ", [
  52. ':id' => $idJob,
  53. ]);
  54. }
  55. static function checkAsyncJobDatabase() {
  56. // `CRM_CONFIG`.`CONF_KEY` = 'Core_AsyncJobs__version'
  57. $dbVersion = (int)DB::getPDO()->fetchValue(" select CONF_VAL from CRM_CONFIG where CONF_KEY = :key ", [ ':key' => self::$CRM_CONFIG_VERSION_KEY ]);
  58. if ($dbVersion < 1) self::upgradeAsyncJobDatabaseToVersion1();
  59. // $dbVersion = (int)DB::getPDO()->fetchValue(" select CONF_VAL from CRM_CONFIG where CONF_KEY = :key ", [ ':key' => 'Core_AsyncJobs__version' ]);
  60. // if ($dbVersion < 2) self::upgradeAsyncJobDatabaseToVersion2();
  61. $dbVersion = (int)DB::getPDO()->fetchValue(" select CONF_VAL from CRM_CONFIG where CONF_KEY = :key ", [ ':key' => self::$CRM_CONFIG_VERSION_KEY ]);
  62. return ($dbVersion < self::$VERSION) ? false : true;
  63. }
  64. static function upgradeAsyncJobDatabaseToVersion1() {
  65. // - insertOrUpdate new row in `CRM_ASYNC_FUNCTIONS` ( $TODAY, $version, $user, $jobName )
  66. // - $JOB_ID = fetchValue select ID from `CRM_ASYNC_FUNCTIONS` where JOB_NAME = $jobName
  67. // - `CRM_ASYNC_FUNCTIONS`.`A_STATUS` default 'WAITING' - not started
  68. // - `CRM_ASYNC_FUNCTIONS`.`A_STATUS`: 'NORMAL' - started
  69. // - `CRM_ASYNC_FUNCTIONS`.`A_STATUS`: 'OFF_HARD' - not running
  70. // - `CRM_ASYNC_FUNCTIONS`.`A_STATUS`: 'DELETED' - removed
  71. $sql = "
  72. CREATE TABLE IF NOT EXISTS `CRM_ASYNC_FUNCTIONS` ( -- list of async function definitions / config
  73. `ID` int(11) NOT NULL AUTO_INCREMENT,
  74. `ID_ZASOB` int(11) NOT NULL DEFAULT 0, -- TODO - register function in CRM_LISTA_ZASOBOW URL_ACTION to set perms
  75. `JOB_NAME` varchar(200) NOT NULL,
  76. `VERSION` int(11) NOT NULL DEFAULT 0,
  77. `LOCK_TYPE` enum('ROW', 'TABLE', 'SYSTEM', 'NO_LOCK') DEFAULT 'ROW',
  78. -- ROW - only one active job per row, eg. create pdf, close FV, @require primaryKey in JOB.LOCK_VALUE
  79. -- TABLE - ony one active job per table, eg. update columns, make report, sync
  80. -- SYSTEM - only one active job
  81. -- TODO USER_... - lock per user
  82. -- NO_LOCK - allow multiple jobs
  83. -- `USER` varchar(20) NOT NULL,
  84. -- `DATE` date NOT NULL,
  85. -- `A_STATUS` enum('WAITING','NORMAL','WARNING','OFF_SOFT','OFF_HARD','DELETED') DEFAULT 'WAITING',
  86. `A_RECORD_CREATE_DATE` datetime NOT NULL,
  87. `A_RECORD_CREATE_AUTHOR` varchar(20) NOT NULL,
  88. `A_RECORD_UPDATE_DATE` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  89. `A_RECORD_UPDATE_AUTHOR` varchar(20) NOT NULL,
  90. PRIMARY KEY (`ID`),
  91. UNIQUE KEY `JOB_NAME` (`JOB_NAME`),
  92. KEY `DATE` (`DATE`),
  93. KEY `A_STATUS` (`A_STATUS`),
  94. KEY `A_RECORD_UPDATE_DATE` (`A_RECORD_UPDATE_DATE`)
  95. ) ENGINE=MyISAM DEFAULT CHARSET=latin2;
  96. ";
  97. // DB::getPDO()->execSql($sql);
  98. $sql = "
  99. CREATE TABLE IF NOT EXISTS `CRM_ASYNC_JOB_LOG` (
  100. `ID` int(11) NOT NULL AUTO_INCREMENT,
  101. `ID_FUNCTION` int(11) NOT NULL,
  102. `ID_SOURCE_JOB` int(11) NOT NULL DEFAULT 0, -- id job
  103. `P_ID` int(11) NOT NULL DEFAULT 0, -- parent job id
  104. `DATE` date NOT NULL,
  105. `VERSION` int(11) NOT NULL DEFAULT 0,
  106. `JOB_NAME` varchar(200) NOT NULL, -- copy from CRM_ASYNC_FUNCTIONS
  107. `LOCK_VALUE` varchar(200) NOT NULL DEFAULT '', -- second part for unique JOB_NAME eg. primaryKey
  108. `USER` varchar(20) NOT NULL, -- user who start this function
  109. `A_STATUS` enum('WAITING','NORMAL','WARNING','OFF_SOFT','OFF_HARD','DELETED') DEFAULT 'WAITING',
  110. `A_RECORD_CREATE_DATE` datetime NOT NULL,
  111. `A_RECORD_CREATE_AUTHOR` varchar(20) NOT NULL,
  112. `A_RECORD_UPDATE_DATE` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  113. `A_RECORD_UPDATE_AUTHOR` varchar(20) NOT NULL,
  114. PRIMARY KEY (`ID`),
  115. -- UNIQUE KEY `JOB_LOCK` (`JOB_NAME`, `LOCK_VALUE`, `USER`), -- add USER to store user click and respond that job is running by other user
  116. KEY `DATE` (`DATE`),
  117. KEY `A_STATUS` (`A_STATUS`),
  118. KEY `A_RECORD_UPDATE_DATE` (`A_RECORD_UPDATE_DATE`)
  119. ) ENGINE=MyISAM DEFAULT CHARSET=latin2;
  120. ";
  121. DB::getPDO()->execSql($sql);
  122. // @usage:
  123. // `CRM_ASYNC_FUNCTIONS`.`JOB_NAME` = '
  124. // route = ant
  125. // -- & path = default_db.in7_dziennik_koresp/test-bash
  126. // & template = test-loop
  127. // & typeName = default_db:IN7_DZIENNIK_KORESP
  128. // & primaryKey = 66263
  129. // & primaryKeyField = ID
  130. // -> `CRM_ASYNC_FUNCTIONS`.`JOB_NAME` =
  131. // namespace = default_db/IN7_DZIENNIK_KORESP
  132. // ant = test-bash
  133. // template = test-loop
  134. // primaryKey = 66263
  135. // -> `CRM_ASYNC_FUNCTIONS`.`JOB_NAME` Format: "{$type}|..."
  136. // -> `CRM_ASYNC_FUNCTIONS`.`JOB_NAME` Format: "Ant|{$namespace}"
  137. // -> `CRM_ASYNC_JOB_LOG`.`LOCK_VALUE` Format: "{$primaryKey}|{$func_name}|..."
  138. // -> `CRM_ASYNC_JOB_LOG`.`LOCK_VALUE` Format: "{$primaryKey}|{$func_name}|{$template}"
  139. // -> Example: JOB_NAME = 'Ant|default_db/IN7_DZIENNIK_KORESP', LOCK_VALUE = '66263|test-bash|test-loop'
  140. // Add fields:
  141. // - function config at execution time:
  142. // - eg LOCK by user | feature | namespace | no_lock -- should contain in name
  143. // - process result - last result - NO - result from file, separate request needed
  144. // IDEA: 2 tables:
  145. // - `Config` - for function config (create row if not exists)
  146. // - `Log` - for log where JOB_ID is created or used from Config table
  147. // then createNewJob:
  148. // 1. fetch job config from CRM_ASYNC_FUNCTIONS_CONFIG
  149. // 1.1 IF 404 then create row, read config from function (how?)
  150. // 1.2 IF exists then check status and lock config
  151. // 1.2.1 IF online and lock then return error
  152. // 1.2.2 IF !online and !lock then create new row in Log table and return correct JOB_ID
  153. self::_upgdateAsyncJobDatabaseVersion($version = 1);
  154. }
  155. static function upgradeAsyncJobDatabaseToVersion2() {
  156. // ...
  157. self::_upgdateAsyncJobDatabaseVersion($version = 2);
  158. }
  159. static function _upgdateAsyncJobDatabaseVersion($version) {
  160. DB::getPDO()->insertOrUpdate('CRM_CONFIG', [
  161. 'CONF_KEY' => self::$CRM_CONFIG_VERSION_KEY,
  162. '@insert' => [
  163. 'CONF_VAL' => $version,
  164. ],
  165. '@update' => [
  166. 'CONF_VAL' => $version,
  167. ]
  168. ]);
  169. }
  170. }