Skip to content

Commit

Permalink
feat: add logger
Browse files Browse the repository at this point in the history
  • Loading branch information
lpatiny committed Jul 24, 2024
1 parent 0316949 commit 8e6b866
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 21 deletions.
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ const sql = `
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
year INTEGER NOT NULL
age REAL NOT NULL
);
INSERT INTO names (name, year) VALUES
('John', 1990),
('Jane', 1985),
('Alice', 2000),
('Bob', 1990);
INSERT INTO names (name, year, age) VALUES
('John', 1990, 30.1),
('Jane', 1985, 29.7),
('Alice', 2000, 25),
('Bob', 1990, 43);
`;
db.exec(sql);

Expand All @@ -52,6 +54,10 @@ search('year:>1990', db); // [{name: 'Alice', year: 2000}]
search('year:!=1990,2000', db); // [{name: 'Jane', year: 1985}]
search('year:<>1990,2000', db); // [{name: 'Jane', year: 1985}]

search('age:30', db); // by default we take into account significative digits and it will search between 29.5 and 30.5
search('age:=30', db); // must be exactly 30, no hit
search('age:=25', db); // must be exactly 25, 1 hit

// when searching for a string we can use the following operators: '^' (starts with), '$' (ends with), '~' (contains), '='. Default to contains. When searching for '=' it is case sensitive otherwise it is not.
search('name:~o', db); // [{name: 'John', year: 1990}, {name: 'Bob', year: 1990}]
search('name:$e', db); // [{name: 'Alice', year: 2000}]
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,14 @@
"better-sqlite3": "^11.1.2",
"eslint": "^8.57.0",
"eslint-config-cheminfo-typescript": "^14.0.0",
"fifo-logger": "^1.0.0",
"jest-matcher-deep-close-to": "^3.0.2",
"prettier": "^3.3.3",
"rimraf": "^6.0.1",
"typescript": "^5.5.3",
"vitest": "^2.0.3"
},
"dependencies": {
"cheminfo-types": "^1.7.3"
}
}
16 changes: 12 additions & 4 deletions src/__tests__/search.names.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@ import { getDBNames } from './utils/getDBNames';
test('names', () => {
const db = getDBNames();
/*
('John', 1990),
('Jane', 1985),
('Alice', 2000),
('Bob', 1990);
('John', 1990, 30.1),
('Jane', 1985, 29.7),
('Alice', 2000, 25),
('Bob', 1990, 43);
*/
expect(search('John', db)).toHaveLength(1);
expect(search('1990', db)).toHaveLength(2);
expect(search('male:true', db)).toHaveLength(2);
expect(search('1990,2000', db)).toHaveLength(3);
expect(search('30', db)).toHaveLength(2);
expect(search('age:30', db)).toHaveLength(2);
expect(search('age:=30', db)).toHaveLength(0);
expect(search('age:=25', db)).toHaveLength(1);
expect(search('30.00', db)).toHaveLength(0);
expect(search('J', db)).toHaveLength(2);
expect(search('year:>1990', db)).toHaveLength(1);
expect(search('name:~o', db)).toHaveLength(2);
Expand All @@ -25,4 +32,5 @@ test('names', () => {
expect(search('year:1990,2000 name:$e,n', db)).toHaveLength(2);
expect(search('year:"1990,2000"', db)).toHaveLength(4);
expect(search('year:"1990","2000"', db)).toHaveLength(3);
expect(search('age:"30","25"', db)).toHaveLength(3);
});
14 changes: 8 additions & 6 deletions src/__tests__/utils/getDBNames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ export function getDBNames(): Database {
CREATE TABLE IF NOT EXISTS names (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
year INTEGER NOT NULL
year INTEGER NOT NULL,
age REAL NOT NULL,
male BOOLEAN NOT NULL
);
INSERT INTO names (name, year) VALUES
('John', 1990),
('Jane', 1985),
('Alice', 2000),
('Bob', 1990);
INSERT INTO names (name, year, age, male) VALUES
('John', 1990, 30.1, 1),
('Jane', 1985, 29.7, 1),
('Alice', 2000, 25, 0),
('Bob', 1990, 43, 0);
`;

db.exec(sql);
Expand Down
5 changes: 5 additions & 0 deletions src/search.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Database } from 'better-sqlite3';
import { Logger } from 'cheminfo-types';

import { Schema } from './types/Schema';
import { TableInfo } from './types/TableInfo';
Expand Down Expand Up @@ -29,6 +30,10 @@ export interface SearchOptions {
* It is possible to specify many fields in which the search will be performed
*/
fieldsAliases?: Record<string, string[]>;
/**
* We can log more information about how queries are executed
*/
logger?: Logger;
}

export type Entry = Record<string, number | string>;
Expand Down
42 changes: 36 additions & 6 deletions src/utils/appendSQLForCriteria.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { Logger } from 'cheminfo-types';

import { QueryCriterium } from '../types/QueryCriterium';
import { Schema } from '../types/Schema';

import { getNumberRange } from './getNumberRange';

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

interface AppendSQLForCriteriaOptions {
defaultFields?: string[];
fieldsAliases?: Record<string, string[]>;
logger?: Logger;
}

/**

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

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Missing JSDoc block description

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

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

Missing JSDoc @returns declaration
Expand Down Expand Up @@ -44,12 +49,17 @@ export function appendSQLForCriteria(
}
// build the corresponding sql part
for (const criterium of criteria) {
criterium.sql = buildSQL(criterium, schema, values);
criterium.sql = buildSQL(criterium, schema, values, options);
}
return values;
}

function buildSQL(criterium: QueryCriterium, schema: Schema, values: Values) {
function buildSQL(
criterium: QueryCriterium,
schema: Schema,
values: Values,
options: AppendSQLForCriteriaOptions,
) {
const sql = [];
for (const field of criterium.fields) {
const column = schema[field];
Expand All @@ -67,15 +77,15 @@ function buildSQL(criterium: QueryCriterium, schema: Schema, values: Values) {
case 'INT':
case 'INTEGER':
{
const newSQL = processNumber(field, criterium, values);
const newSQL = processNumber(field, criterium, values, options);
if (newSQL) {
sql.push(newSQL);
}
}
break;
case 'BOOLEAN':
{
const newSQL = processBoolean(field, criterium, values);
const newSQL = processBoolean(field, criterium, values, options);
if (newSQL) {
sql.push(newSQL);
}
Expand Down Expand Up @@ -133,8 +143,10 @@ function processNumber(
field: string,
criterium: QueryCriterium,
values: Values,
options: AppendSQLForCriteriaOptions,
) {
const operator = criterium.operator || '=';
const { logger } = options;
const operator = criterium.operator || '~';
const sqls = [];
let joinOperator = 'OR';
for (let valueIndex = 0; valueIndex < criterium.values.length; valueIndex++) {
Expand All @@ -146,13 +158,28 @@ function processNumber(
const valueFieldName = `${field}_${criterium.index}_${valueIndex}`;

switch (operator) {
case '~':
{
// we consider by default that a number is not exact by default
const { min, max } = getNumberRange(value);
values[`${valueFieldName}_min`] = min;
values[`${valueFieldName}_max`] = max;
sqls.push(
`${field} BETWEEN :${valueFieldName}_min AND :${valueFieldName}_max`,
);
}
break;
case '=':
values[valueFieldName] = Number(value);
sqls.push(`${field} = :${valueFieldName}`);
break;
case '..':
{
const [min, max] = value.split('..').map(Number);
if (Number.isNaN(min) || Number.isNaN(max)) {
if (logger) logger.info(`Invalid range for ${field}: ${value}`);
continue;
}
values[`${valueFieldName}_min`] = min;
values[`${valueFieldName}_max`] = max;
sqls.push(
Expand Down Expand Up @@ -192,9 +219,12 @@ function processBoolean(
field: string,
criterium: QueryCriterium,
values: Values,
options: AppendSQLForCriteriaOptions,
) {
const { logger } = options;
if (criterium.values.length > 1) {
throw new Error('Boolean does not support multiple values');
if (logger) logger.info('Boolean does not support multiple values');
return '';
}
const value = getBooleanValue(criterium.values[0]);
if (value === null) {
Expand Down

0 comments on commit 8e6b866

Please sign in to comment.