Модуль:Collect
Для документации этого модуля может быть создана страница Модуль:Collect/doc
local collect = {}
local tools = require 'Module:Tools'
local cq = mw.ext.cargo.query
--[[
Функция осуществляет выборку полей (строка fields) из таблицы Cargo с менем journal.
Критерий выборки определяется массивом gFio, где каждая строка содержит поля имени
(l, f, m, d). Результатом является выборка из базы с дополнительными колонками
'#eq' и '#ap', обозначающими точное или примерное соответствие. Дополнительно, если
задан параметр — ссылка на массив approx, то в нем собирается список документов
с примерным соответствием (в формате «[документ] = true»).
Результат
— выборка (см. выше)
— число строк с точным соответствием (если approx задан) или примерным
(если approx == nil)
Пустые f и m — это пустые строки, а не nil
пустой d = nil
Используемые поля таблицы Cargo. Пустое значение строки, хотя и хранится
(и работает во WHERE) как NULL, но в массиве отдается как пустая строка
| nLast = String (size=100)
| nFirst = String (size=60)
| nMiddle = String (size=100)
| nDisambig = String (size=20)
| nPrecision = String (size=1)
| _pageName
--]]
function collect.dbtable( gFio, journal, fields, approx )
local where = {}
local tmp
for _, fio in ipairs( gFio ) do
tmp = 'nLast="' .. fio.l .. '"'
if fio.f ~= '' then
tmp = tmp .. ' AND (nFirst IS NULL OR nFirst LIKE "' .. mw.ustring.sub( fio.f, 1, 1 ) .. '%")'
end
if fio.m ~= '' then
tmp = tmp .. ' AND (nMiddle IS NULL OR nMiddle LIKE "' .. mw.ustring.sub( fio.m, 1, 1 ) .. '%")'
end
if fio.d then
tmp = tmp .. ' AND (nDisambig IS NULL OR nDisambig="' .. fio.d .. '")'
end
where[#where+1] = tmp
end
where = table.concat( where, ' OR ' )
local query = cq( journal, fields, { where = where, limit = 1001 } )
-- do return query end
local flen, mlen, fcmp, mcmp
local fdb, mdb
local eqCount = 0
for _, row in ipairs( query ) do
fdb, mdb = row.nFirst or '', row.nMiddle or ''
flen, mlen = string.len( fdb ), string.len( mdb )
for _, fio in ipairs( gFio ) do
if row.nDisambig == ( fio.d or '' ) and fio.f == fdb and fio.m == mdb then
if row.nPrecision ~= '' then
row['#ap'] = true
else
row['#eq'] = true
end
elseif ( row.nDisambig~='' and fio.d and row.nDisambig ~= fio.d )
or (row.nDisambig == '(*)' and approx ) then
-- не подходит
else
fcmp, mcmp = math.min( flen, string.len( fio.f ) ), math.min( mlen, string.len( fio.m ) )
if string.sub( fio.f, 1, fcmp ) == string.sub( fdb, 1, fcmp )
and string.sub( fio.m, 1, mcmp ) == string.sub( mdb, 1, mcmp ) then
row['#ap'] = true
end
end
end
if row['#eq'] then
eqCount = eqCount + 1
elseif row['#ap'] then
if approx then
approx[row._pageName] = true
else
eqCount = eqCount + 1
end
end
end
-- итого у нас в query готовая выборка, где у некоторых строк стоят флаги #eq и #ap
return query, eqCount
end
return collect