"use strict";const{cppdb}=require("../util");function wrapFactory(e){return function(t,r,o,...n){const i={module:t,database:r,table:o},a=apply.call(e,i,n);if("object"!=typeof a||null===a)throw new TypeError(`Virtual table module "${t}" did not return a table definition object`);return parseTableDefinition(a,"returned",t)}}function parseTableDefinition(e,t,r){if(!hasOwnProperty.call(e,"rows"))throw new TypeError(`Virtual table module "${r}" ${t} a table definition without a "rows" property`);if(!hasOwnProperty.call(e,"columns"))throw new TypeError(`Virtual table module "${r}" ${t} a table definition without a "columns" property`);const o=e.rows;if("function"!=typeof o||Object.getPrototypeOf(o)!==GeneratorFunctionPrototype)throw new TypeError(`Virtual table module "${r}" ${t} a table definition with an invalid "rows" property (should be a generator function)`);let n,i=e.columns;if(!Array.isArray(i)||!(i=[...i]).every(e=>"string"==typeof e))throw new TypeError(`Virtual table module "${r}" ${t} a table definition with an invalid "columns" property (should be an array of strings)`);if(i.length!==new Set(i).size)throw new TypeError(`Virtual table module "${r}" ${t} a table definition with duplicate column names`);if(!i.length)throw new RangeError(`Virtual table module "${r}" ${t} a table definition with zero columns`);if(hasOwnProperty.call(e,"parameters")){if(n=e.parameters,!Array.isArray(n)||!(n=[...n]).every(e=>"string"==typeof e))throw new TypeError(`Virtual table module "${r}" ${t} a table definition with an invalid "parameters" property (should be an array of strings)`)}else n=inferParameters(o);if(n.length!==new Set(n).size)throw new TypeError(`Virtual table module "${r}" ${t} a table definition with duplicate parameter names`);if(n.length>32)throw new RangeError(`Virtual table module "${r}" ${t} a table definition with more than the maximum number of 32 parameters`);for(const e of n)if(i.includes(e))throw new TypeError(`Virtual table module "${r}" ${t} a table definition with column "${e}" which was ambiguously defined as both a column and parameter`);let a=2;if(hasOwnProperty.call(e,"safeIntegers")){const o=e.safeIntegers;if("boolean"!=typeof o)throw new TypeError(`Virtual table module "${r}" ${t} a table definition with an invalid "safeIntegers" property (should be a boolean)`);a=+o}let l=!1;if(hasOwnProperty.call(e,"directOnly")&&(l=e.directOnly,"boolean"!=typeof l))throw new TypeError(`Virtual table module "${r}" ${t} a table definition with an invalid "directOnly" property (should be a boolean)`);return[`CREATE TABLE x(${[...n.map(identifier).map(e=>`${e} HIDDEN`),...i.map(identifier)].join(", ")});`,wrapGenerator(o,new Map(i.map((e,t)=>[e,n.length+t])),r),n,a,l]}function wrapGenerator(e,t,r){return function*(...o){const n=o.map(e=>Buffer.isBuffer(e)?Buffer.from(e):e);for(let e=0;e<t.size;++e)n.push(null);for(const i of e(...o))if(Array.isArray(i))extractRowArray(i,n,t.size,r),yield n;else{if("object"!=typeof i||null===i)throw new TypeError(`Virtual table module "${r}" yielded something that isn't a valid row object`);extractRowObject(i,n,t,r),yield n}}}function extractRowArray(e,t,r,o){if(e.length!==r)throw new TypeError(`Virtual table module "${o}" yielded a row with an incorrect number of columns`);const n=t.length-r;for(let o=0;o<r;++o)t[o+n]=e[o]}function extractRowObject(e,t,r,o){let n=0;for(const i of Object.keys(e)){const a=r.get(i);if(void 0===a)throw new TypeError(`Virtual table module "${o}" yielded a row with an undeclared column "${i}"`);t[a]=e[i],n+=1}if(n!==r.size)throw new TypeError(`Virtual table module "${o}" yielded a row with missing columns`)}function inferParameters({length:e}){if(!Number.isInteger(e)||e<0)throw new TypeError("Expected function.length to be a positive integer");const t=[];for(let r=0;r<e;++r)t.push(`$${r+1}`);return t}module.exports=function(e,t){if("string"!=typeof e)throw new TypeError("Expected first argument to be a string");if(!e)throw new TypeError("Virtual table module name cannot be an empty string");let r=!1;if("object"==typeof t&&null!==t)r=!0,t=defer(parseTableDefinition(t,"used",e));else{if("function"!=typeof t)throw new TypeError("Expected second argument to be a function or a table definition object");t=wrapFactory(t)}return this[cppdb].table(t,e,r),this};const{hasOwnProperty}=Object.prototype,{apply}=Function.prototype,GeneratorFunctionPrototype=Object.getPrototypeOf(function*(){}),identifier=e=>`"${e.replace(/"/g,'""')}"`,defer=e=>()=>e;