Completed
Push — work-fleets ( 8474eb...046d2e )
by SuperNova.WS
08:49
created

SnDbCachedOperator   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 347
Duplicated Lines 10.37 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 36
loc 347
rs 8.6206
ccs 0
cts 140
cp 0
wmc 50
lcom 1
cbo 3

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A db_del_record_by_id() 6 16 4
A db_del_record_list() 8 18 4
A db_get_record_by_id() 0 6 3
C db_get_record_list() 0 62 17
B db_upd_record_by_id() 0 24 5
B db_upd_record_list() 0 19 5
A db_ins_record() 11 17 3
B db_ins_field_set() 11 22 4
A db_lock_tables() 0 6 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like SnDbCachedOperator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SnDbCachedOperator, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Created by Gorlum 01.08.2016 21:40
5
 */
6
class SnDbCachedOperator {
7
  // Кэш индексов - ключ MD5-строка от суммы ключевых строк через | - менять | на что-то другое перед поиском и назад - после поиска
8
  // Так же в индексах могут быть двойные вхождения - например, названия планет да и вообще
9
  // Придумать спецсимвол для NULL
10
11
  /*
12
  TODO Кэш:
13
  1. Всегда дешевле использовать процессор, чем локальную память
14
  2. Всегда дешевле использовать локальную память, чем общую память всех процессов
15
  3. Всегда дешевле использовать общую память всех процессов, чем обращаться к БД
16
17
  Кэш - многоуровневый: локальная память-общая память-БД
18
  БД может быть сверхкэширующей - см. HyperNova. Это реализуется на уровне СН-драйвера БД
19
  Предусмотреть вариант, когда уровни кэширования совпадают, например когда нет xcache и используется общая память
20
  */
21
22
  // TODO Автоматически заполнять эту таблицу. В случае кэша в памяти - делать show table при обращении к таблице
23
  public static $location_info = array(
24
    LOC_USER => array(
25
      P_TABLE_NAME => 'users',
26
      P_ID         => 'id',
27
      P_OWNER_INFO => array(),
28
    ),
29
30
    LOC_PLANET => array(
31
      P_TABLE_NAME => 'planets',
32
      P_ID         => 'id',
33
      P_OWNER_INFO => array(
34
        LOC_USER => array(
35
          P_LOCATION    => LOC_USER,
36
          P_OWNER_FIELD => 'id_owner',
37
        ),
38
      ),
39
    ),
40
41
    LOC_UNIT => array(
42
      P_TABLE_NAME => 'unit',
43
      P_ID         => 'unit_id',
44
      P_OWNER_INFO => array(
45
        LOC_USER => array(
46
          P_LOCATION    => LOC_USER,
47
          P_OWNER_FIELD => 'unit_player_id',
48
        ),
49
      ),
50
    ),
51
52
    LOC_QUE => array(
53
      P_TABLE_NAME => 'que',
54
      P_ID         => 'que_id',
55
      P_OWNER_INFO => array(
56
        array(
57
          P_LOCATION    => LOC_USER,
58
          P_OWNER_FIELD => 'que_player_id',
59
        ),
60
61
        array(
62
          P_LOCATION    => LOC_PLANET,
63
          P_OWNER_FIELD => 'que_planet_id_origin',
64
        ),
65
66
        array(
67
          P_LOCATION    => LOC_PLANET,
68
          P_OWNER_FIELD => 'que_planet_id',
69
        ),
70
      ),
71
    ),
72
73
    LOC_FLEET => array(
74
      P_TABLE_NAME => 'fleets',
75
      P_ID         => 'fleet_id',
76
      P_OWNER_INFO => array(
77
        array(
78
          P_LOCATION    => LOC_USER,
79
          P_OWNER_FIELD => 'fleet_owner',
80
        ),
81
82
        array(
83
          P_LOCATION    => LOC_USER,
84
          P_OWNER_FIELD => 'fleet_target_owner',
85
        ),
86
87
        array(
88
          P_LOCATION    => LOC_PLANET,
89
          P_OWNER_FIELD => 'fleet_start_planet_id',
90
        ),
91
92
        array(
93
          P_LOCATION    => LOC_PLANET,
94
          P_OWNER_FIELD => 'fleet_end_planet_id',
95
        ),
96
      ),
97
    ),
98
  );
99
100
  protected $db;
101
102
  /**
103
   * SnDbCachedOperator constructor.
104
   *
105
   * @param \Common\GlobalContainer $gc
106
   */
107
  public function __construct($gc) {
108
    $this->db = $gc->db;
109
  }
110
111
  public function db_del_record_by_id($location_type, $safe_record_id) {
112
    if (!($safe_record_id = idval($safe_record_id))) {
113
      return false;
114
    }
115
116
    $id_field = static::$location_info[$location_type][P_ID];
117
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
118 View Code Duplication
    if ($result = $this->db->doDelete("DELETE FROM `{{{$table_name}}}` WHERE `{$id_field}` = {$safe_record_id}")) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Bug introduced by
The method doDelete does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
119
      // Обновляем данные только если ряд был затронут
120
      if ($this->db->db_affected_rows()) {
0 ignored issues
show
Bug introduced by
The method db_affected_rows does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
121
        SnCache::cache_unset($location_type, $safe_record_id);
122
      }
123
    }
124
125
    return $result;
126
  }
127
128
  public function db_del_record_list($location_type, $condition) {
129
    if (!($condition = trim($condition))) {
130
      return false;
131
    }
132
133
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
134
135 View Code Duplication
    if ($result = $this->db->doDelete("DELETE FROM `{{{$table_name}}}` WHERE {$condition}")) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Bug introduced by
The method doDelete does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
136
      // Обновляем данные только если ряд был затронут
137
      if ($this->db->db_affected_rows()) {
0 ignored issues
show
Bug introduced by
The method db_affected_rows does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
138
        // Обнуление кэша, потому что непонятно, что поменялось
139
        // TODO - когда будет структурированный $condition можно будет делать только cache_unset по нужным записям
140
        SnCache::cache_clear($location_type);
141
      }
142
    }
143
144
    return $result;
145
  }
146
147
  /**
148
   * Возвращает информацию о записи по её ID
149
   *
150
   * @param int       $location_type
151
   * @param int|array $record_id_unsafe
152
   *    <p>int - ID записи</p>
153
   *    <p>array - запись пользователя с установленным полем P_ID</p>
154
   * @param bool      $for_update @deprecated
155
   * @param string    $fields @deprecated список полей или '*'/'' для всех полей
156
   * @param bool      $skip_lock Указывает на то, что не нужно блокировать запись //TODO и не нужно сохранять в кэше
157
   *
158
   * @return array|false
159
   *    <p>false - Нет записи с указанным ID</p>
160
   *    <p>array - запись</p>
161
   */
162
  public function db_get_record_by_id($location_type, $record_id_unsafe, $for_update = false, $fields = '*', $skip_lock = false) {
0 ignored issues
show
Unused Code introduced by
The parameter $for_update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $fields is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $skip_lock is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
163
    $id_field = static::$location_info[$location_type][P_ID];
164
    $record_id_safe = idval(is_array($record_id_unsafe) && isset($record_id_unsafe[$id_field]) ? $record_id_unsafe[$id_field] : $record_id_unsafe);
165
166
    return classSupernova::$gc->cacheOperator->db_get_record_list($location_type, "`{$id_field}` = {$record_id_safe}", true, false);
0 ignored issues
show
Bug introduced by
The method db_get_record_list does only exist in SnDbCachedOperator, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
167
  }
168
169
  public function db_get_record_list($location_type, $filter = '', $fetch = false, $no_return = false) {
170
    if (SnCache::isQueryCacheByLocationAndFilterEmpty($location_type, $filter)) {
171
      SnCache::queryCacheResetByLocationAndFilter($location_type, $filter);
172
173
      $location_info = &static::$location_info[$location_type];
174
      $id_field = $location_info[P_ID];
175
176
      if ($this->db->getTransaction()->check(false)) {
0 ignored issues
show
Bug introduced by
The method getTransaction does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
177
        // Проходим по всем родителям данной записи
178
        foreach ($location_info[P_OWNER_INFO] as $owner_data) {
179
          $owner_location_type = $owner_data[P_LOCATION];
180
          $parent_id_list = array();
181
          // Выбираем родителей данного типа и соответствующие ИД текущего типа
182
          $query = $this->db->doSelect(
0 ignored issues
show
Bug introduced by
The method doSelect does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
183
            "SELECT
184
              distinct({{{$location_info[P_TABLE_NAME]}}}.{$owner_data[P_OWNER_FIELD]}) AS parent_id
185
            FROM {{{$location_info[P_TABLE_NAME]}}}" .
186
            ($filter ? ' WHERE ' . $filter : '') .
187
            ($fetch ? ' LIMIT 1' : ''));
188
          while ($row = db_fetch($query)) {
189
            // Исключаем из списка родительских ИД уже заблокированные записи
190
            if (!SnCache::cache_lock_get($owner_location_type, $row['parent_id'])) {
191
              $parent_id_list[$row['parent_id']] = $row['parent_id'];
192
            }
193
          }
194
195
          // Если все-таки какие-то записи еще не заблокированы - вынимаем текущие версии из базы
196
          if ($indexes_str = implode(',', $parent_id_list)) {
197
            $parent_id_field = static::$location_info[$owner_location_type][P_ID];
198
            classSupernova::$gc->cacheOperator->db_get_record_list($owner_location_type,
0 ignored issues
show
Bug introduced by
The method db_get_record_list does only exist in SnDbCachedOperator, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
199
              $parent_id_field . (count($parent_id_list) > 1 ? " IN ({$indexes_str})" : " = {$indexes_str}"), $fetch, true);
200
          }
201
        }
202
      }
203
204
      $query = $this->db->doSelect(
205
        "SELECT * FROM {{{$location_info[P_TABLE_NAME]}}}" .
206
        (($filter = trim($filter)) ? " WHERE {$filter}" : '')
207
        . " FOR UPDATE"
208
      );
209
      while ($row = db_fetch($query)) {
210
        // Caching record in row cache
211
        SnCache::cache_set($location_type, $row);
212
        // Making ref to cached record in query cache
213
        SnCache::queryCacheSetByFilter($location_type, $filter, $row[$id_field]);
214
      }
215
    }
216
217
    if ($no_return) {
218
      return true;
219
    } else {
220
      $result = false;
221
      foreach (SnCache::getQueriesByLocationAndFilter($location_type, $filter) as $key => $value) {
222
        $result[$key] = $value;
223
        if ($fetch) {
224
          break;
225
        }
226
      }
227
228
      return $fetch ? (is_array($result) ? reset($result) : false) : $result;
229
    }
230
  }
231
232
  /**
233
   * @param int    $location_type
234
   * @param int    $record_id
235
   * @param string $set - SQL SET structure
236
   *
237
   * @return array|bool|mysqli_result|null
238
   */
239
  public function db_upd_record_by_id($location_type, $record_id, $set) {
240
    if (!($record_id = idval($record_id)) || !($set = trim($set))) {
241
      return false;
242
    }
243
244
    $id_field = static::$location_info[$location_type][P_ID];
245
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
246
    // TODO Как-то вернуть может быть LIMIT 1 ?
247
    if ($result = $this->db->doUpdate("UPDATE {{{$table_name}}} SET {$set} WHERE `{$id_field}` = {$record_id}")) {
0 ignored issues
show
Bug introduced by
The method doUpdate does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
248
      if ($this->db->db_affected_rows()) {
0 ignored issues
show
Bug introduced by
The method db_affected_rows does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
249
        // Обновляем данные только если ряд был затронут
250
        // TODO - переделать под работу со структурированными $set
251
252
        // Тут именно так, а не cache_unset - что бы в кэшах автоматически обновилась запись. Будет нужно на будущее
253
        //static::$data[$location_type][$record_id] = null;
0 ignored issues
show
Unused Code Comprehensibility introduced by
79% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
254
        SnCache::cacheUnsetElement($location_type, $record_id);
255
        // Вытаскиваем обновленную запись
256
        $this->db_get_record_by_id($location_type, $record_id);
257
        SnCache::cache_clear($location_type, false); // Мягкий сброс - только $queries
258
      }
259
    }
260
261
    return $result;
262
  }
263
264
  /**
265
   * @param int    $location_type
266
   * @param string $set
267
   * @param string $condition
268
   *
269
   * @return array|bool|mysqli_result|null
270
   */
271
  public function db_upd_record_list($location_type, $set, $condition) {
272
    if (!($set = trim($set))) {
273
      return false;
274
    }
275
276
    $condition = trim($condition);
277
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
278
279
    if ($result = $this->db->doUpdate("UPDATE {{{$table_name}}} SET " . $set . ($condition ? ' WHERE ' . $condition : ''))) {
0 ignored issues
show
Bug introduced by
The method doUpdate does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
280
281
      if ($this->db->db_affected_rows()) { // Обновляем данные только если ряд был затронут
0 ignored issues
show
Bug introduced by
The method db_affected_rows does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
282
        // Поскольку нам неизвестно, что и как обновилось - сбрасываем кэш этого типа полностью
283
        // TODO - когда будет структурированный $condition и $set - перепаковывать данные
284
        SnCache::cache_clear($location_type, true);
285
      }
286
    }
287
288
    return $result;
289
  }
290
291
  /**
292
   * @param int    $location_type
293
   * @param string $set
294
   *
295
   * @return array|bool|false|mysqli_result|null
296
   */
297
  public function db_ins_record($location_type, $set) {
298
    $set = trim($set);
299
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
300 View Code Duplication
    if ($result = $this->db->doInsert("INSERT INTO `{{{$table_name}}}` SET {$set}")) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Bug introduced by
The method doInsert does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
301
      if ($this->db->db_affected_rows()) // Обновляем данные только если ряд был затронут
0 ignored issues
show
Bug introduced by
The method db_affected_rows does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
302
      {
303
        $record_id = $this->db->db_insert_id();
0 ignored issues
show
Bug introduced by
The method db_insert_id does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
304
        // Вытаскиваем запись целиком, потому что в $set могли быть "данные по умолчанию"
305
        $result = $this->db_get_record_by_id($location_type, $record_id);
306
        // Очищаем второстепенные кэши - потому что вставленная запись могла повлиять на результаты запросов или локация или еще чего
307
        // TODO - когда будет поддержка изменения индексов и локаций - можно будет вызывать её
308
        SnCache::cache_clear($location_type, false); // Мягкий сброс - только $queries
309
      }
310
    }
311
312
    return $result;
313
  }
314
315
  public function db_ins_field_set($location_type, $field_set, $serialize = false) {
316
    // TODO multiinsert
317
    !sn_db_field_set_is_safe($field_set) ? $field_set = sn_db_field_set_make_safe($field_set, $serialize) : false;
318
    sn_db_field_set_safe_flag_clear($field_set);
319
    $values = implode(',', $field_set);
320
    $fields = implode(',', array_keys($field_set));
321
322
    $table_name = static::$location_info[$location_type][P_TABLE_NAME];
323 View Code Duplication
    if ($result = $this->db->doInsert("INSERT INTO `{{{$table_name}}}` ({$fields}) VALUES ({$values});")) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Bug introduced by
The method doInsert does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
324
      if ($this->db->db_affected_rows()) {
0 ignored issues
show
Bug introduced by
The method db_affected_rows does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
325
        // Обновляем данные только если ряд был затронут
326
        $record_id = $this->db->db_insert_id();
0 ignored issues
show
Bug introduced by
The method db_insert_id does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
327
        // Вытаскиваем запись целиком, потому что в $set могли быть "данные по умолчанию"
328
        $result = $this->db_get_record_by_id($location_type, $record_id);
329
        // Очищаем второстепенные кэши - потому что вставленная запись могла повлиять на результаты запросов или локация или еще чего
330
        // TODO - когда будет поддержка изменения индексов и локаций - можно будет вызывать её
331
        SnCache::cache_clear($location_type, false); // Мягкий сброс - только $queries
332
      }
333
    }
334
335
    return $result;
336
  }
337
338
339
  /**
340
   * Блокирует указанные таблицу/список таблиц
341
   *
342
   * @param string|array $tables Таблица/список таблиц для блокировки. Названия таблиц - без префиксов
343
   * <p>string - название таблицы для блокировки</p>
344
   * <p>array - массив, где ключ - имя таблицы, а значение - условия блокировки элементов</p>
345
   */
346
  public function db_lock_tables($tables) {
347
    $tables = is_array($tables) ? $tables : array($tables => '');
348
    foreach ($tables as $table_name => $condition) {
349
      $this->db->doSelect("SELECT 1 FROM {{{$table_name}}}" . ($condition ? ' WHERE ' . $condition : ''));
0 ignored issues
show
Bug introduced by
The method doSelect does only exist in db_mysql, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
350
    }
351
  }
352
}
353