SKY / WINGS / FIRST /
SQL1

Файл первого крыла main/sky.php для работы с БД предоставляет функции: sql(), sqlf(), sqls(), fetch(), cnt(), escape(), константы fetch, row, методы $sky->begin(), $sky->end().

Функция sql() заменяет функцию mysqli_query() (если, к примеру, используется модуль mysqli_), кроме того, проверяет результат выполнения на наличие ошибок и регистрирует их, делает трассировку SQL запросов. Для запросов DELETE, UPDATE, REPLACE, дополнительно выполняет mysqli_affected_rows(), что часто бывает необходимо. Для запросов INSERT, дополнительно выполняет mysqli_insert_id(). Для запросов SELECT (наиболее частых и разнообразных, по сравнению с ранее указанными), вообще, имеет расширенный синтаксис.

Если делать обычный запрос, без префиксов, функция наиболее близко соответствует простому запросу с использованием mysqli_query(). При использовании префиксов, модификация функционала следующая:

+select.. - часто бывает нужно просто прочитать в БД содержимое одной ячейки одного ряда. В этом случае удобно использовать такой префикс. Функция прямо вернет значение этой ячейки.

-select.. - дополнительно выполняется mysqli_fetch_row(). Префикс удобно использовать, когда нужно считать один ряд таблицы и выдать результат в виде числового массива.

~select.. - дополнительно выполняется mysqli_fetch_assoc(). Функционал подобен предыдущему случаю, но результат возвращается в виде ассоциативного массива.

@select.. - считывает все ряды результата и помещает их в числовой массив, причем ключами массивов, являются значения первой указанной в запросе SELECT колонки. Это более удобно в практическом использовании, чем, когда ключами массивов, является просто порядковая нумерация рядов запроса, результат который возвращается функциями типа fetchAll().

%select.. - тоже самое как в предыдущем случае: ключи - значения первой колонки, а ключи вложенных массивов - имена колонок таблицы. Если в запросе всего 2 колонки, то значения не массивы, а значения второй колонки результатов. Такая выдача результатов, опять таки более удобна и практична.

^select.. - запрос с таким префиксов, предназначен для работы по схеме: eval(sql("^select ..")). При таких вызовах генерируются переменные с префиксом $r_ соответствующие именам колонок запроса, например $r_id.

>select.. - дополнительно выполняется mysqli_fetch_object(). Результат выдается в виде объекта.

Функция sqlf() похожа на sql(), подобно тому как похожа функция printf() на print(). Первый параметр функции должен содержать SQL запрос с форматированием, подобно тому которое поддерживает printf(), а остальные параметры функции, - значения подставляемые в форматированную строку-запрос. Дополнительно параметром может быть массив. Если ключи целочисленные, массив можно использовать для генерации строки перечисления имен колонок результата в запросах SELECT. Если массивы ассоциативные, где ключи - имена колонок, функция sqlf() будет генерировать из массивов строку по правилам построения запросов INSERT, UPDATE, REPLACE. Например:

001
002
003
004
005
sqlf("insert into city %s", [
  'id' => 'null',
  'country_id' => 1,
  'city' => "'London'",
]);

Функция sqls() позволяет выполнять несколько запросов одновременно, перечисленные через ";".

Константа "fetch" содержит исполняемый код и предназначена для работы по схеме:

001
002
003
004
005
$q sql("select * from articles");
for (; eval(fetch); ) {
  # you can access column value like $r_id for each row
  # or all row like $r, so one column like $r['id']
}

При этом значения, каждого считанного ряда помещаются в переменные с префиксом $r_, например $r_id. Также весь ряд значений помещается в числовой массив, подобно как работает $r = sql("~select * from ..."); # one row

Константа "row" предназначена для работы по подобной схеме, но внутри файлов вида и каждый ряд результата выдается в виде объекта плюс возможна модификация рядов результата в callback функции. Пример для MVC с хорошим стилем (здесь префикс e_ дополняет объект $e_list, кодом в $e_list->row, в котором используется константа row, для организации отложенных итераций)
):

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
// in controller for "list" type page
  function empty_c() {
    # .. some code
    $this->_v = [
      'title_h1' => 'Main page', # will accesible in view file via $v_title_h1
      'e_list' => $this->t_blog->listing()
      # .. other view variables
    ];
  }
 
// in model
  function listing($user_id = 0) {
    # .. some code
    return [
      'title' => 'The listing..',
      'callback' => [$this, 'callback_row'],
      'query' => $q = sql("select .. from .. "),
      'num_rows' => cnt($q),
      # other...
    ];
  }
 
  function callback_row(&$row) {
    $row->login = strtoupper($row->login); #modify column
    $row->rubric = $this->ary($row->rubric_id); # add new property
    # .. other code
  }
 
// in view file, print listing
<h1><?=$v_title_h1?></h1>
<!-- ..some data -->
<h2><?=$e_list->title?></h2>
<?for(;eval($e_list->row);):?>
  rubric: <?=$row->rubric?>
  <!-- other outputs -->
<?endfor?>

Методы $sky->begin() и $sky->end() предназначены для организации транзакций в таблицах innoDB, по схеме:

001
002
003
004
if ($sky->begin()) {
  # several SQL queries and PHP code
  $sky->end();
}

Если начало транзакции удачно, выполняется несколько SQL запросов и PHP код. В конце транзакции нужно выполнить $sky->end(). Если были ошибки в SQL или PHP, делается ROLLBACK, иначе выполняется COMMIT и транзакция закрывается. Если $sky->begin() имеет параметр, дополнительно можно сделать "LOCK TABLES" ... вначале транзакции и "UNLOCK TABLES" в конце. Если $sky->end() имеет "callable" параметр и в течении транзакции произошла ошибка, - метод или функция, содержащаяся в параметре, будет вызвана. Если ошибок не было, функция не будет вызвана.
опубликовано ENERGY - 19 Sep 2015 05:29 GMT
последнее редактирование - 15 Dec 2015 14:52 GMT
комментировать