Модуль:Collect

Материал из Кадровый состав НКВД 1935-1939
Перейти к: навигация, поиск

Для документации этого модуля может быть создана страница Модуль: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