Module:UtilsCargo

local p = {} local h = {}

local frame = mw.getCurrentFrame

function p.query(tables, fields, args) return mw.ext.cargo.query(tables, fields, args) end

local function escape(str) return string.gsub(str, "'", "\\'") end

function p.allOf(...) local query for i, v in ipairs({...}) do		if type(v) == "table" then for k, v in pairs(v) do				v = escape(v) query = h.andClause(query, string.format("%s='%s'", k, v)) end else query = h.andClause(query, v)		end end return query end

function p.holdsAll(field, values) local query for i, value in ipairs(values) do		value = escape(value) if #values > 1 then -- Workaround for Cargo bug: https://phabricator.wikimedia.org/T267498 -- __full lists all the categories as a string separated by pipes. -- Specific regex is needed to account for categories which are at the start or end of the string, which will be missing a pipe. -- (^|\\|) matches the beginning -- ($|\\|) matches the end query = h.andClause(query, field..\\|)..value..\\|)') else query = h.andClause(query, string.format("%s HOLDS '%s'", field, value)) end end return query end

function p.holdsAny(field, values) local query for i, value in ipairs(values) do		value = escape(value) query = h.orClause(query, string.format("%s HOLDS '%s'", field, value)) end return query end

function p.IN(field, values) local inValues = {} for i, value in ipairs(values) do		value = escape(value) value = string.format("'%s'", value) inValues[i] = value end inValues = table.concat(inValues, ", ") if inValues == "" then inValues = "''" end return string.format("%s IN (%s)", field, inValues) end

function h.andClause(query, clause) return h.addClause("AND", query, clause) end

function h.orClause(query, clause) return h.addClause("OR", query, clause) end

function h.addClause(operator, query, clause) if not query or query == "" then return clause end return table.concat({query, operator, clause}, " ") end

return p