1- // 0. @sql-extra/createindex (createIndex)
2- function createIndex ( nam , tab , exp , opt = { } , z = '' ) {
3- z += `CREATE INDEX IF NOT EXISTS "${ nam } " ON "${ tab } " ` ;
4- if ( opt . method ) z += `USING ${ opt . method } ` ;
5- return z + `(${ exp } );\n` ;
6- } ;
7- // 1. @sql-extra/createtable (createTable)
1+ /**
2+ * Generates SQL command for CREATE TABLE.
3+ * @param {string } nam table name
4+ * @param {object } cols columns {name: type}
5+ * @param {object } opt options {pk}
6+ * @param {string } opt.pk primary key (null => none)
7+ * @param {string } z please dont use
8+ * @returns {string } SQL command
9+ */
810function createTable ( nam , cols , opt = { } , z = '' ) {
911 z += `CREATE TABLE IF NOT EXISTS "${ nam } " (` ;
1012 for ( var k in cols )
1113 z += `"${ k } " ${ cols [ k ] } , ` ;
1214 if ( opt . pk ) z += `PRIMARY KEY("${ opt . pk } "), ` ;
1315 return z . replace ( / , $ / , '' ) + `);\n` ;
14- } ;
15- // 2. @sql-extra/createview (createView)
16+ }
17+
18+
19+ /**
20+ * Generates SQL command for CREATE INDEX.
21+ * @param {string } nam index name
22+ * @param {string } tab table name
23+ * @param {string } exp index expression
24+ * @param {object } opt options {method}
25+ * @param {string } opt.method index method (btree)
26+ * @param {string } z please dont use
27+ * @returns {string } SQL query
28+ */
29+ function createIndex ( nam , tab , exp , opt = { } , z = '' ) {
30+ z += `CREATE INDEX IF NOT EXISTS "${ nam } " ON "${ tab } " ` ;
31+ if ( opt . method ) z += `USING ${ opt . method } ` ;
32+ return z + `(${ exp } );\n` ;
33+ }
34+
35+
36+ /**
37+ * Generates SQL command for CREATE VIEW.
38+ * @param {string } nam view name
39+ * @param {string } qry view query
40+ * @param {object } opt options
41+ * @param {string } z please dont use
42+ * @returns {string } SQL command
43+ */
1644function createView ( nam , qry , opt = null , z = '' ) {
1745 z += `CREATE OR REPLACE VIEW "${ nam } " AS ${ qry } ;\n` ;
1846 return z ;
19- } ;
20- // 3. @sql-extra/insertinto (insertInto)
21- function addRow3 ( val , z = '' , i = 0 ) {
47+ }
48+
49+
50+ function addRow ( val , z = '' , i = 0 ) {
2251 if ( i === 0 ) {
2352 for ( var k in val )
2453 z += `"${ k } ", ` ;
@@ -31,55 +60,59 @@ function addRow3(val, z='', i=0) {
3160 z += '),\n(' ;
3261 return z ;
3362} ;
34- function stream3 ( tab , strm , opt = { } , z = '' ) {
63+
64+ /**
65+ * Generates SQL command for INSERT INTO.
66+ * @param {string } tab table name
67+ * @param {Stream<object> } strm a readable stream with row objects {column: value}
68+ * @param {object } opt options {pk}
69+ * @param {string } opt.pk primary key, on conflict (null => none)
70+ * @param {string } z please dont use
71+ * @returns {string } SQL command
72+ */
73+ function insertIntoStream ( tab , strm , opt = { } , z = '' ) {
3574 var i = - 1 ;
3675 z += `INSERT INTO "${ tab } " (` ;
3776 return new Promise ( ( fres , frej ) => {
3877 strm . on ( 'error' , frej ) ;
39- strm . on ( 'data' , ( val ) => z = addRow3 ( val , z , ++ i ) ) ;
78+ strm . on ( 'data' , ( val ) => z = addRow ( val , z , ++ i ) ) ;
4079 strm . on ( 'end' , ( ) => {
4180 z = z . replace ( / \) , \n \( $ / , '' ) + ')' ;
4281 if ( opt . pk ) z += `\nON CONFLICT ("${ opt . pk } ") DO NOTHING` ;
4382 fres ( z + ';\n' ) ;
4483 } ) ;
4584 } ) ;
46- } ;
85+ }
86+
87+ /**
88+ * Generates SQL command for INSERT INTO.
89+ * @param {string } tab table name
90+ * @param {Array<object> } vals row objects {column: value}
91+ * @param {object } opt options {pk}
92+ * @param {string } opt.pk primary key, on conflict (null => none)
93+ * @param {string } z please dont use
94+ * @returns {string } SQL command
95+ */
4796function insertInto ( tab , vals , opt = { } , z = '' ) {
4897 var i = - 1 ;
4998 z += `INSERT INTO "${ tab } " (` ;
5099 for ( var val of vals )
51- z = addRow3 ( val , z , ++ i ) ;
100+ z = addRow ( val , z , ++ i ) ;
52101 z = z . replace ( / \) , \n \( $ / , '' ) + ')' ;
53102 if ( opt . pk ) z += `\nON CONFLICT ("${ opt . pk } ") DO NOTHING` ;
54103 return z + ';\n' ;
55- } ;
56- insertInto . stream = stream3 ;
57- // 4. @sql-extra/matchtsquery (matchTsquery)
58- function matchTsquery ( tab , wrds , tsv = '"tsvector"' , opt = { } ) {
59- var col = opt . columns || '*' , nrm = opt . normalization || 0 ;
60- for ( var i = wrds . length , z = '' ; i > 0 ; i -- ) {
61- var qry = wrds . slice ( 0 , i ) . join ( ' ' ) . replace ( / ( [ \' \" ] ) / g, '$1$1' ) ;
62- z += `SELECT ${ col } , '${ i } '::INT AS "matchTsquery" FROM "${ tab } "` ;
63- z += ` WHERE ${ tsv } @@ plainto_tsquery('${ qry } ')` ;
64- if ( opt . order ) z += ` ORDER BY ts_rank(${ tsv } , plainto_tsquery('${ qry } '), ${ nrm } ) DESC` ;
65- z += ' UNION ALL\n' ;
66- }
67- z = z . substring ( 0 , z . length - 11 ) ;
68- if ( opt . limit ) z += ` LIMIT ${ opt . limit } ` ;
69- z += ';\n' ;
70- return z ;
71- } ;
72- // 5. @sql-extra/selecttsquery (selectTsquery)
73- function selectTsquery ( tab , qry , tsv = '"tsvector"' , opt = { } ) {
74- var col = opt . columns || '*' , nrm = opt . normalization || 0 ;
75- var z = `SELECT ${ col } FROM "${ tab } " WHERE ${ tsv } @@ plainto_tsquery('${ qry } ')` ;
76- if ( opt . order ) z += ` ORDER BY ts_rank(${ tsv } , plainto_tsquery('${ qry } '), ${ nrm } ) DESC` ;
77- if ( opt . limit ) z += ` LIMIT ${ opt . limit } ` ;
78- z += `;\n` ;
79- return z ;
80- } ;
81- // 6. @sql-extra/setuptable (setupTable)
82- function index6 ( nam , cols , opt = { } , z = '' ) {
104+ }
105+ insertInto . stream = insertIntoStream ;
106+
107+
108+ function tsvector ( cols ) {
109+ var z = '' ;
110+ for ( var k in cols )
111+ if ( cols [ k ] ) z += `setweight(to_tsvector('english', "${ k } "), '${ cols [ k ] } ')||` ;
112+ return z . replace ( / \| \| $ / , '' ) ;
113+ }
114+
115+ function setupTableIndex ( nam , cols , opt = { } , z = '' ) {
83116 if ( opt . tsvector ) {
84117 var tv = tsvector ( opt . tsvector ) ;
85118 z += createView ( nam + '_tsvector' , `SELECT *, ${ tv } AS "tsvector" FROM "${ nam } "` ) ;
@@ -93,30 +126,87 @@ function index6(nam, cols, opt={}, z='') {
93126 }
94127 }
95128 return z ;
96- } ;
129+ }
130+
131+ /**
132+ * Generates SQL commands to setup table (create, insert, index).
133+ * @param {string } nam table name
134+ * @param {object } cols columns {name: type}
135+ * @param {Array<object> } vals row objects {column: value}
136+ * @param {object } opt options for createTable/View/Index/, insertInto
137+ * @param {string } z please dont use
138+ */
97139function setupTable ( nam , cols , vals = null , opt = { } , z = '' ) {
98140 z = createTable ( nam , cols , opt , z ) ;
99141 if ( vals ) z = insertInto ( nam , vals , opt , z ) ;
100- return index6 ( nam , cols , opt , z ) ;
101- } ;
102- setupTable . index = index6 ;
103- // 7. @sql-extra/tableexists (tableExists)
142+ return setupTableIndex ( nam , cols , opt , z ) ;
143+ }
144+ setupTable . index = setupTableIndex ;
145+
146+
147+ /**
148+ * Generates SQL command for table exists check.
149+ * @param {string } nam table name
150+ * @returns {string } SQL command
151+ */
104152function tableExists ( nam ) {
105153 return `SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name='${ nam } ');\n` ;
106- } ;
107- // 8. @sql-extra/tsvector (tsvector)
108- function tsvector ( cols ) {
109- var z = '' ;
110- for ( var k in cols )
111- if ( cols [ k ] ) z += `setweight(to_tsvector('english', "${ k } "), '${ cols [ k ] } ')||` ;
112- return z . replace ( / \| \| $ / , '' ) ;
113- } ;
114- exports . createIndex = createIndex ;
154+ }
155+
156+
157+ /**
158+ * Generates SQL command for SELECT with tsquery.
159+ * @param {string } tab table name
160+ * @param {string } qry plain query words
161+ * @param {string } tsv tsvector ("tsvector")
162+ * @param {object } opt options {columns, order, limit, normalization}
163+ * @param {string } opt.columns select columns (*)
164+ * @param {boolean } opt.order order rows? (false)
165+ * @param {number } opt.limit limit rows (0 => no)
166+ * @param {number } opt.normalization rank normalization (0 => ignores the document length)
167+ * @returns {string } SQL command
168+ */
169+ function selectTsquery ( tab , qry , tsv = '"tsvector"' , opt = { } ) {
170+ var col = opt . columns || '*' , nrm = opt . normalization || 0 ;
171+ var z = `SELECT ${ col } FROM "${ tab } " WHERE ${ tsv } @@ plainto_tsquery('${ qry } ')` ;
172+ if ( opt . order ) z += ` ORDER BY ts_rank(${ tsv } , plainto_tsquery('${ qry } '), ${ nrm } ) DESC` ;
173+ if ( opt . limit ) z += ` LIMIT ${ opt . limit } ` ;
174+ z += `;\n` ;
175+ return z ;
176+ }
177+
178+
179+ /**
180+ * Generates SQL query for matching words with tsquery.
181+ * @param {string } tab table name
182+ * @param {Array<string> } wrds match words
183+ * @param {string } tsv tsvector ("tsvector")
184+ * @param {object } opt options {columns, order, limit, normalization}
185+ * @param {string } opt.columns select columns (*)
186+ * @param {boolean } opt.order order rows? (false)
187+ * @param {number } opt.limit limit rows (0 => no)
188+ * @param {number } opt.normalization rank normalization (0 => ignores the document length)
189+ * @returns {string } SQL command
190+ */
191+ function matchTsquery ( tab , wrds , tsv = '"tsvector"' , opt = { } ) {
192+ var col = opt . columns || '*' , nrm = opt . normalization || 0 ;
193+ for ( var i = wrds . length , z = '' ; i > 0 ; i -- ) {
194+ var qry = wrds . slice ( 0 , i ) . join ( ' ' ) . replace ( / ( [ \' \" ] ) / g, '$1$1' ) ;
195+ z += `SELECT ${ col } , '${ i } '::INT AS "matchTsquery" FROM "${ tab } "` ;
196+ z += ` WHERE ${ tsv } @@ plainto_tsquery('${ qry } ')` ;
197+ if ( opt . order ) z += ` ORDER BY ts_rank(${ tsv } , plainto_tsquery('${ qry } '), ${ nrm } ) DESC` ;
198+ z += ' UNION ALL\n' ;
199+ }
200+ z = z . substring ( 0 , z . length - 11 ) ;
201+ if ( opt . limit ) z += ` LIMIT ${ opt . limit } ` ;
202+ z += ';\n' ;
203+ return z ;
204+ }
115205exports . createTable = createTable ;
206+ exports . createIndex = createIndex ;
116207exports . createView = createView ;
117208exports . insertInto = insertInto ;
118- exports . matchTsquery = matchTsquery ;
119- exports . selectTsquery = selectTsquery ;
120209exports . setupTable = setupTable ;
121210exports . tableExists = tableExists ;
122- exports . tsvector = tsvector ;
211+ exports . selectTsquery = selectTsquery ;
212+ exports . matchTsquery = matchTsquery ;
0 commit comments