Skip to content

Commit

Permalink
fix: ignore filtering values that do not have the right type
Browse files Browse the repository at this point in the history
  • Loading branch information
lpatiny committed Jul 21, 2024
1 parent ad3eb8d commit e4a01b4
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 16 deletions.
5 changes: 3 additions & 2 deletions src/__tests__/search.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getDBNames } from './utils/getDBNames';

test('text', () => {
const db = getDB();
expect(search('text-12', db)).toHaveLength(2);
expect(search('textColumn:text-1', db)).toHaveLength(22);
expect(search('textColumn:=text-1', db)).toHaveLength(1);
expect(search('textColumn:text-1', db, { limit: 5 })).toHaveLength(5);
Expand Down Expand Up @@ -52,7 +53,7 @@ test('errors', () => {
);
});

test('names', () => {
test.only('names', () => {
const db = getDBNames();
/*
('John', 1990),
Expand All @@ -71,6 +72,6 @@ test('names', () => {
expect(search('year:!=1990,2000', db)).toHaveLength(1);
expect(search('year:<>1990,2000', db)).toHaveLength(1);
expect(search('year:1990,2000 name:$e,n', db)).toHaveLength(2);
expect(search('year:"1990,2000"', db)).toHaveLength(0);
expect(search('year:"1990,2000"', db)).toHaveLength(4);
expect(search('year:"1990","2000"', db)).toHaveLength(3);
});
9 changes: 5 additions & 4 deletions src/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Database } from 'better-sqlite3';

import { Schema } from './types/Schema';
import { TableInfo } from './types/TableInfo';
import { buildQueryCriteria } from './utils/buildQueryCriteria';
import { appendSQLForCriteria } from './utils/appendSQLForCriteria';
import { parseQueryString } from './utils/parseQueryString';

export interface SearchOptions {
Expand Down Expand Up @@ -42,8 +42,10 @@ export function search(
): Entry[] {
const { tableName = getTableName(db), limit = 1000 } = options;
const schema = getSchema(db, tableName);
const criteria = parseQueryString(queryString);
const values = buildQueryCriteria(criteria, schema, options);
let criteria = parseQueryString(queryString);
const values = appendSQLForCriteria(criteria, schema, options);
// some criteria may should be removed because they don't have sql property
criteria = criteria.filter((criterium) => criterium.sql);

const sqls: string[] = [];
sqls.push(`SELECT * FROM ${tableName}`);
Expand All @@ -55,7 +57,6 @@ export function search(
if (limit) {
sqls.push(`LIMIT ${limit}`);
}
//console.log(sqls);
//console.log(values);
const stmt = db.prepare(sqls.join(' '));
return stmt.all(values) as Entry[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Schema } from '../types/Schema';

type Values = Record<string, number | string>;

interface BuildQueryCriteriaOptions {
interface AppendSQLForCriteriaOptions {
defaultFields?: string[];
fieldsAliases?: Record<string, string[]>;
}
Expand All @@ -14,10 +14,10 @@ interface BuildQueryCriteriaOptions {
* @param schema

Check warning on line 14 in src/utils/appendSQLForCriteria.ts

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Missing JSDoc @param "schema" description
* @param options

Check warning on line 15 in src/utils/appendSQLForCriteria.ts

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Missing JSDoc @param "options" description
*/
export function buildQueryCriteria(
export function appendSQLForCriteria(
criteria: QueryCriterium[],
schema: Schema,
options: BuildQueryCriteriaOptions = {},
options: AppendSQLForCriteriaOptions = {},
): Record<string, number | string> {
const { defaultFields = Object.keys(schema), fieldsAliases = {} } = options;
const values: Values = {};
Expand Down Expand Up @@ -54,15 +54,30 @@ function buildSQL(criterium: QueryCriterium, schema: Schema, values: Values) {

switch (column.type) {
case 'TEXT':
sql.push(processText(field, criterium, values));
{
const newSQL = processText(field, criterium, values);
if (newSQL) {
sql.push(newSQL);
}
}
break;
case 'REAL':
case 'INT':
case 'INTEGER':
sql.push(processNumber(field, criterium, values));
{
const newSQL = processNumber(field, criterium, values);
if (newSQL) {
sql.push(newSQL);
}
}
break;
case 'BOOLEAN':
sql.push(processBoolean(field, criterium, values));
{
const newSQL = processBoolean(field, criterium, values);
if (newSQL) {
sql.push(newSQL);
}
}
break;
case 'BLOB':
case 'NULL':
Expand All @@ -73,6 +88,9 @@ function buildSQL(criterium: QueryCriterium, schema: Schema, values: Values) {
);
}
}
if (sql.length === 0) {
return '';
}
return `(${sql.join(' OR ')})`;
}

Expand Down Expand Up @@ -119,7 +137,10 @@ function processNumber(
let joinOperator = 'OR';
for (let valueIndex = 0; valueIndex < criterium.values.length; valueIndex++) {
const value = criterium.values[valueIndex];

// is it really a number ? We should skip otherwise
if (operator !== '..' && Number.isNaN(Number(value))) {
continue;
}
const valueFieldName = `${field}_${criterium.index}_${valueIndex}`;

switch (operator) {
Expand Down Expand Up @@ -159,6 +180,9 @@ function processNumber(
);
}
}
if (sqls.length === 0) {
return '';
}
return `(${sqls.join(` ${joinOperator} `)})`;
}

Expand All @@ -170,7 +194,10 @@ function processBoolean(
if (criterium.values.length > 1) {
throw new Error('Boolean does not support multiple values');
}
const value = criterium.values[0];
const value = getBooleanValue(criterium.values[0]);
if (value === null) {
return '';
}
const operator = criterium.operator || '=';
switch (operator) {
case '=':
Expand All @@ -182,3 +209,14 @@ function processBoolean(
);
}
}

function getBooleanValue(value: string): boolean | null {
value = value.toLowerCase();
if (value === 'true' || value === '1' || value === 'yes') {
return true;
}
if (value === 'false' || value === '0' || value === 'no') {
return false;
}
return null;
}
4 changes: 2 additions & 2 deletions src/utils/parseQueryString.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { QueryCriterium } from '../types/QueryCriterium';

import { splitString } from './splitString';
import { trimQuotes } from './trimQuotes';

Expand Down Expand Up @@ -37,7 +38,6 @@ export function parseQueryString(string: string): QueryCriterium[] {
token = trimQuotes(token);
queryCriteria.push({ fields, operator, values, negate, index: index++ });
}

// if no values we wkip
// if no values
return queryCriteria.filter((criterium) => criterium.values.length > 0);
}

0 comments on commit e4a01b4

Please sign in to comment.