В связи с высказаным мной предположением в части 3-й и 4-й я решил модифицировать модуль базы. Изменение этого модуля повлекло модификацию всех исполнительных. Но это того стоило. Модификация состоит в том, что для вызова СУБД — зависимых запросов можно настроить однотипные процедуры, принимающие параметры на входе.

Рассмотрим функцию database.select_from_where(select, from, where), которая часто используется в процедурах для получения табличной информации:

function database.select_from_where(select, from, where)

	text = "SELECT " .. select .. " FROM " .. from

	if where ~= nil then 
		text = text .. " WHERE " .. where .. " ;"
	else
		text = text .. " ;"
	end

	query = database.link()
	thread = query:execute(text)
	result = thread:fetch({}, "a")	
	return result

end


Вызывается это благолепие командой:

base = require "database"
data = base.select_from_where( "number, name" , "customer" , nil )

Дальше всё это обрабатывается через цикл и построчно извлекаются данные:
	while data do
		print("| № " .. data.number .. " | " .. data.name .. " | " .. data.phone .. " |" )
		data = thread:fetch(data, "a")
	end

Здесь заполняется первоначальный вызов функции fetch() для последующего снижения дублирования везде, где только возможно. Таким образом мы вырезаем половину кода из модулей исполнения и передаём им массив с данными по запросу.

Следующая функция — database.update_set_where(update, set, where) — используется для обновления данных без индексного удаления. Это ситуации, в которых нам надо изменить данные позиции / пользователя без перелапачивания документов и данные выплат по позиции:

function database.update_set_where(update, set, where)

	text = "UPDATE " .. update .. " SET " .. set .. " WHERE " .. where .. " ;"
	query = database.link()
	thread = query:execute(text)	

end

В функцию забивается имя таблицы, имя столбца для изменения и условие обновления. Здесь можно указать ячейку с конкретным значением полей или целую группу. В случае некорректного ввода данных (например, изменилась цена на несколько категорий) информацию можно изменить очень быстро.

Важное замечание при создании процедур, управляющих изменением данных базы:
Когда работаете с базами Вам необходимо корректно обрабатывать следующие аспекты:
  • Соблюдение изоляции текстовых аргументов запроса (чаще всего одинарной кавычкой, но зависит от СУБД);
  • Соблюдение пространства между ключевыми словами (SELECT, WHERE, FROM и прочих из языка SQL) и данными запроса;
  • Соблюдение порядка запроса и изолирующих знаков — сначала идут ключевые слова, заключившие данные в своих блоках, затем завершаем дело точкой с запятой.
  • В случае изменения больших объёмов однотипных данных (запрос на внос — вынос данных, создание / изменение документа и прочее, что передаётся в едином логическом блоке) рекомендуется использовать механизм транзакций. Но это в случае превышения суммарного объёма записей свыше 10000 штук.

Без этих правил запись / чтение данных будет стопориться при каждой ошибке запроса.

Функция database.delete_from_where(from, where) используется для ликвидации данных в таблицах. дабы исключить случайное уничтожение всех данных в таблице, функция создаёт строку с параметром сравнения:

function database.delete_from_where(from, where)

	text = "DELETE FROM " .. from .. " WHERE " .. where .. " ;"
	query = database.link()
	thread = query:execute(text)	

end

И последняя, часто используемая функция — database.insert_into_values(table, fields, values) — предназначенная для вставки данных:

function database.insert_into_values(table, fields, values)

	text = "INSERT INTO " .. table .. " ( " .. fields .. " ) VALUES ( " .. values .. ") ;"
	query = database.link()
	thread = query:execute(text)

end

Как видите, во всех функциях, кроме SELECT'а, используется элементарное исполнение запроса. Прикол в том, что базы SQLite3 по окончании записи / модификации строки не выдают значение индеска, как это делает Firebird. По этой причине приходится запускать поиск индекса добавленной строки при последующем добавлении индекса в связаные таблицы.

Таким образом, все вышеуказаные функции сводят 4-6 строк на исполнение запроса в модулях бизнес-логики до 1-5 строчек на каждую. Такая оптимизация вдогонку улучшила удобочитаемость исполнительных модулей.

P.S. Маленькая просьба — если хотите передать замечание по этому циклу статей, прошу предварительно прочитать статью «Разработка микро-учётной системы на lua, часть вторая. Постановка задачи», в которой я указываю условия разработки программы и функции, которые на неё возлагаются. Учитывайте это.
Поделиться с друзьями
-->

Комментарии (5)


  1. PerlPower
    01.06.2016 22:58
    +4

    При всем моем уважении, ваша лабораторная работа затянулась.


  1. napa3um
    02.06.2016 10:12
    +1

    Используйте db:prepare для параметрических запросов вместо конструирования запросов из строк. Для получения индекса последней вставленной записи используйте db:lastid.


    1. hantenellotf
      02.06.2016 10:13

      Это относится к LuaSQL-SQLite?


      1. napa3um
        02.06.2016 10:18

        Да, похоже, не db:lastid, а db:last_insert_rowid. Вы в документацию принципиально не подглядываете?


        1. hantenellotf
          02.06.2016 10:46

          К сведению принял.