Test Failed
Push — trunk ( 769658...cc4c01 )
by SuperNova.WS
15:09
created

Updater::transactionCommit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/** @noinspection SqlResolve */
3
4
/**
5
 * Created by Gorlum 01.03.2019 6:03
6
 */
7
8
namespace Core;
9
10
use classConfig;
11
use DBAL\db_mysql;
12
use DBAL\DbFieldDescription;
13
use DBAL\DbIndexDescription;
14
use mysqli_result;
15
use SN;
16
17
class Updater {
18
19
  protected $update_tables = [];
20
21
  /**
22
   * @var classConfig $config
23
   */
24
  protected $config;
25
  /**
26
   * @var db_mysql $db
27
   */
28
  protected $db;
29
30
  protected $upd_log = '';
31
32
  public $new_version = 0;
33
  protected $old_server_status;
34
35
  // Does updater terminated successfully
36
  public $successTermination = false;
37
38
  public function __construct() {
39
    $this->config = SN::$gc->config;
40
    $this->db     = SN::$gc->db;
41
42
    $this->new_version = floatval($this->config->db_version);
43
44
    // Closing any transaction that can be opened to this moment
45
    $this->upd_do_query('ROLLBACK;', true);
46
47
    $this->config->reset();
48
    $this->config->db_loadAll();
49
50
    $this->config->db_prefix    = $this->db->db_prefix; // Оставить пока для совместимости
51
    $this->config->cache_prefix = SN::$cache_prefix;
0 ignored issues
show
Bug Best Practice introduced by
The property cache_prefix does not exist on classConfig. Since you implemented __set, consider adding a @property annotation.
Loading history...
52
53
    $this->config->debug = 0;
54
55
    $this->checkVersionSupport();
56
57
    ini_set('memory_limit', '1G');
58
    set_time_limit($this->config->upd_lock_time + 10);
59
    $this->upd_do_query('SET FOREIGN_KEY_CHECKS=0;', true);
60
61
    $this->upd_log_message('Update started. Disabling server');
62
    $this->old_server_status = $this->config->pass()->game_disable;
63
    $this->config->db_saveItem('game_disable', GAME_DISABLE_UPDATE);
64
    $this->upd_log_message('Server disabled.');
65
66
    $this->upd_log_message('Now looking DB for upgrades...');
67
  }
68
69
  public function __destruct() {
70
    if ($this->successTermination) {
71
      $this->upd_log_message('Upgrade complete.');
72
    } else {
73
      $this->upd_log_message('Upgrade was aborted! DB can be in invalid state!');
74
    }
75
76
    $this->upd_do_query('SET FOREIGN_KEY_CHECKS=1;', true);
77
78
    SN::$cache->unset_by_prefix('lng_');
79
80
    if ($this->new_version) {
81
      $this->config->pass()->db_version = $this->new_version;
82
      $this->upd_log_message("<span style='color: green;'>DB version is now {$this->new_version}</span>");
83
    } else {
84
      $this->upd_log_message("DB version didn't changed from {$this->config->db_version}");
85
    }
86
87
    $this->config->db_loadAll();
88
    /*
89
    if($user['authlevel'] >= 3) {
90
      print(str_replace("\r\n", '<br>', $upd_log));
91
    }
92
    */
93
    $this->db->schema()->clear();
94
95
    $this->upd_log_message('Restoring server status');
96
    $this->config->pass()->game_disable = $this->old_server_status;
97
  }
98
99
  public function upd_log_message($message) {
100
    global $sys_log_disabled, $debug;
101
102
    if ($sys_log_disabled) {
103
//    print("{$message}<br />");
104
    } else {
105
      $this->upd_log .= "{$message}\r\n";
106
      $debug->warning($message, 'Database Update', 103);
107
    }
108
  }
109
110
  public function upd_log_version_update() {
111
    $this->upd_add_more_time();
112
    $this->upd_log_message("Detected outdated version {$this->new_version}. Upgrading...");
113
  }
114
115
  public function upd_check_key($key, $default_value, $condition = false) {
116
    global $sys_log_disabled;
117
118
    $this->config->pass()->$key;
119
    if ($condition || !isset($this->config->$key)) {
120
      $this->upd_add_more_time();
121
      if (!$sys_log_disabled) {
122
        $this->upd_log_message("Updating config key '{$key}' with value '{$default_value}'");
123
      }
124
      $this->config->pass()->$key = $default_value;
125
    } else {
126
      $this->config->pass()->$key = null;
127
    }
128
  }
129
130
131
  /**
132
   * @param string       $table_name
133
   * @param string|array $declaration
134
   * @param string       $tableOptions
135
   *
136
   * @return bool|mysqli_result
137
   */
138
  public function upd_create_table($table_name, $declaration, $tableOptions = '') {
139
    $result = null;
140
141
    if (!$this->isTableExists($table_name)) {
142
      if (is_array($declaration)) {
143
        $declaration = implode(',', $declaration);
144
      }
145
      $declaration = trim($declaration);
146
      if (substr($declaration, 0, 1) != '(') {
147
        $declaration = "($declaration)";
148
      }
149
      $tableOptions = trim($tableOptions);
150
      if (!empty($tableOptions)) {
151
        $declaration .= $tableOptions;
152
      }
153
      $result = $this->upd_do_query("CREATE TABLE IF NOT EXISTS `{$this->config->db_prefix}{$table_name}` {$declaration}");
154
      $error  = SN::$db->db_error();
155
      if ($error) {
156
        die("Creating error for table `{$table_name}`: {$error}<br />" . dump($declaration));
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
157
      }
158
159
      $this->db->schema()->clear();
160
    }
161
162
    return $result;
163
  }
164
165
  /**
166
   * @param string          $table
167
   * @param string|string[] $alters
168
   * @param bool            $condition
169
   *
170
   * @return bool|mysqli_result|null
171
   */
172
  public function upd_alter_table($table, $alters, $condition = true) {
173
    if (!$condition) {
174
      return null;
175
    }
176
177
    $this->upd_add_more_time();
178
    $alters_print = is_array($alters) ? dump($alters) : $alters;
179
    $this->upd_log_message("Altering table '{$table}' with alterations {$alters_print}");
180
181
    if (!is_array($alters)) {
182
      $alters = array($alters);
183
    }
184
185
    $alters = implode(',', $alters);
186
    // foreach($alters as $table_name => )
187
    $qry = "ALTER TABLE {$this->config->db_prefix}{$table} {$alters};";
188
189
    $result = $this->upd_do_query($qry);
190
    $error  = SN::$db->db_error();
191
    if ($error) {
192
      die("Altering error for table `{$table}`: {$error}<br />{$alters_print}");
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
193
    }
194
195
    $this->db->schema()->clear();
196
197
    return $result;
198
  }
199
200
  public function upd_drop_table($table_name) {
201
    $this->db->db_sql_query("DROP TABLE IF EXISTS {$this->config->db_prefix}{$table_name};");
202
    $this->db->schema()->clear();
203
  }
204
205
  public function upd_add_more_time($time = 0) {
206
    global $sys_log_disabled;
207
208
    $time = $time ? $time : $this->config->upd_lock_time;
209
    !$sys_log_disabled ? $this->config->pass()->var_db_update_end = SN_TIME_NOW + $time : false;
210
    set_time_limit($time);
211
  }
212
213
  /**
214
   * @param int $id
215
   *
216
   * @return bool
217
   */
218
  public function updPatchExists($id) {
219
    $q = $this->upd_do_query("SELECT 1 FROM `{{server_patches}}` WHERE `id` = " . intval($id), true);
220
221
    return !empty(db_fetch($q));
222
  }
223
224
  /**
225
   * @param int $id
226
   */
227
  public function updPatchRegister($id) {
228
    $this->upd_do_query("INSERT INTO `{{server_patches}}` SET `id` = " . intval($id));
229
  }
230
231
  /**
232
   * @param int      $patchId
233
   * @param callable $callable
234
   * @param bool     $preCheck - [PATCH_REGISTER|PATCH_PRE_CHECK]
235
   */
236
  public function updPatchApply($patchId, $callable, $preCheck = PATCH_REGISTER) {
237
    if (!$this->updPatchExists($patchId)) {
238
      $callable();
239
240
      if ($preCheck == PATCH_REGISTER) {
241
        $this->updPatchRegister($patchId);
242
      }
243
    }
244
  }
245
246
  /**
247
   * @param string $query
248
   * @param bool   $no_log
249
   *
250
   * @return bool|mysqli_result
251
   */
252
  public function upd_do_query($query, $no_log = false) {
253
    $this->upd_add_more_time();
254
255
    if (!$no_log) {
256
      $this->upd_log_message("Performing query '{$query}'");
257
    }
258
259
    if (strpos($query, '{{') !== false) {
260
      foreach ($this->db->schema()->getSnTables() as $tableName => $cork) {
261
        $query = str_replace("{{{$tableName}}}", $this->db->db_prefix . $tableName, $query);
262
      }
263
    }
264
    $result = $this->db->db_sql_query($query) or die('Query error for ' . $query . ': ' . SN::$db->db_error());
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
265
266
    return $result;
267
  }
268
269
  protected function checkVersionSupport() {
270
    if ($this->config->db_version < DB_VERSION_MIN) {
271
//  print("This version does not supports upgrades from SN below v{$minVersion}. Please, use SN v42 to upgrade old database.<br />
272
//Эта версия игры не поддерживает обновление движка версий ниже v{$minVersion}. Пожалуйста, используйте SN v42 для апгрейда со старых версий игры.<br />");
273
      die(
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
274
        'Internal error! Updater detects DB version LESSER then can be handled!<br />
275
    Possible you have VERY out-of-date SuperNova version<br />
276
    Use first SuperNova version not greater then  ' . DB_VERSION_MIN . ' to make preliminary upgrade and then use newest version again<br />
277
    List of available releases <a href="https://github.com/supernova-ws/SuperNova/releases">GIT repository</a>'
278
      );
279
    } elseif ($this->config->db_version > DB_VERSION) {
280
      $this->config->pass()->var_db_update_end = SN_TIME_NOW;
281
      die(
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
282
      'Internal error! Updater detects DB version greater then can be handled!<br />
283
    Possible you have out-of-date SuperNova version<br />
284
    Please upgrade your server from <a href="http://github.com/supernova-ws/SuperNova">GIT repository</a>'
285
      );
286
    }
287
  }
288
289
  /**
290
   * @param $table
291
   * @param $field
292
   *
293
   * @return DbFieldDescription
294
   */
295
  public function getFieldDescription($table, $field) {
296
    return $this->db->schema()->getTableSchema($table)->fields[$field];
297
  }
298
299
  /**
300
   * @param $table
301
   * @param $index
302
   *
303
   * @return DbIndexDescription
304
   */
305
  public function getIndexDescription($table, $index) {
306
    return $this->db->schema()->getTableSchema($table)->indexes[$index];
307
  }
308
309
  public function isTableExists($table) {
310
    return $this->db->schema()->isSnTableExists($table);
311
  }
312
313
  public function isFieldExists($table, $field) {
314
    return $this->db->schema()->isFieldExists($table, $field);
315
  }
316
317
  public function isIndexExists($table, $index) {
318
    return $this->db->schema()->isIndexExists($table, $index);
319
  }
320
321
  public function transactionStart() {
322
//    $this->upd_do_query('START TRANSACTION;', true);
323
    $this->db->transactionStart();
324
  }
325
326
  public function transactionCommit() {
327
//    $this->upd_do_query('COMMIT;', true);
328
    $this->db->transactionCommit();
329
  }
330
331
}
332