mirror of
https://github.com/frappe/books.git
synced 2024-12-22 10:58:59 +00:00
incr: add deleteAll
- fix db where clauses
This commit is contained in:
parent
6805ebcaba
commit
2a5686058d
@ -266,6 +266,12 @@ export default class DatabaseCore extends DatabaseBase {
|
||||
)) as FieldValueMap[];
|
||||
}
|
||||
|
||||
async deleteAll(schemaName: string, filters: QueryFilter): Promise<number> {
|
||||
const builder = this.knex!(schemaName);
|
||||
this.#applyFiltersToBuilder(builder, filters);
|
||||
return await builder.delete();
|
||||
}
|
||||
|
||||
async getSingleValues(
|
||||
...fieldnames: ({ fieldname: string; parent?: string } | string)[]
|
||||
): Promise<SingleValue<RawValue>> {
|
||||
@ -444,10 +450,35 @@ export default class DatabaseCore extends DatabaseBase {
|
||||
// {"date": [">=", "2017-09-09", "<=", "2017-11-01"]}
|
||||
// => `date >= 2017-09-09 and date <= 2017-11-01`
|
||||
|
||||
const filtersArray = [];
|
||||
const filtersArray = this.#getFiltersArray(filters);
|
||||
for (const i in filtersArray) {
|
||||
const filter = filtersArray[i];
|
||||
const field = filter[0] as string;
|
||||
const operator = filter[1];
|
||||
const comparisonValue = filter[2];
|
||||
const type = i === '0' ? 'where' : 'andWhere';
|
||||
|
||||
if (operator === '=') {
|
||||
builder[type](field, comparisonValue);
|
||||
} else if (
|
||||
operator === 'in' &&
|
||||
(comparisonValue as (string | null)[]).includes(null)
|
||||
) {
|
||||
const nonNulls = (comparisonValue as (string | null)[]).filter(
|
||||
Boolean
|
||||
) as string[];
|
||||
builder[type](field, operator, nonNulls).orWhere(field, null);
|
||||
} else {
|
||||
builder[type](field, operator as string, comparisonValue as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#getFiltersArray(filters: QueryFilter) {
|
||||
const filtersArray = [];
|
||||
for (const field in filters) {
|
||||
const value = filters[field];
|
||||
|
||||
let operator: string | number = '=';
|
||||
let comparisonValue = value as string | number | (string | number)[];
|
||||
|
||||
@ -477,25 +508,7 @@ export default class DatabaseCore extends DatabaseBase {
|
||||
}
|
||||
}
|
||||
|
||||
filtersArray.map((filter) => {
|
||||
const field = filter[0] as string;
|
||||
const operator = filter[1];
|
||||
const comparisonValue = filter[2];
|
||||
|
||||
if (operator === '=') {
|
||||
builder.where(field, comparisonValue);
|
||||
} else if (
|
||||
operator === 'in' &&
|
||||
(comparisonValue as (string | null)[]).includes(null)
|
||||
) {
|
||||
const nonNulls = (comparisonValue as (string | null)[]).filter(
|
||||
Boolean
|
||||
) as string[];
|
||||
builder.where(field, operator, nonNulls).orWhere(field, null);
|
||||
} else {
|
||||
builder.where(field, operator as string, comparisonValue as string);
|
||||
}
|
||||
});
|
||||
return filtersArray;
|
||||
}
|
||||
|
||||
async #getColumnDiff(schemaName: string): Promise<ColumnDiff> {
|
||||
|
@ -549,3 +549,78 @@ test('CRUD dependent schema', async function (t) {
|
||||
|
||||
await db.close();
|
||||
});
|
||||
|
||||
test('db deleteAll', async (t) => {
|
||||
const db = await getDb();
|
||||
|
||||
const emailOne = 'one@temp.com';
|
||||
const emailTwo = 'two@temp.com';
|
||||
const emailThree = 'three@temp.com';
|
||||
|
||||
const phoneOne = '1';
|
||||
const phoneTwo = '2';
|
||||
|
||||
const customers = [
|
||||
{ name: 'customer-a', phone: phoneOne, email: emailOne },
|
||||
{ name: 'customer-b', phone: phoneOne, email: emailOne },
|
||||
{ name: 'customer-c', phone: phoneOne, email: emailTwo },
|
||||
{ name: 'customer-d', phone: phoneOne, email: emailTwo },
|
||||
{ name: 'customer-e', phone: phoneTwo, email: emailTwo },
|
||||
{ name: 'customer-f', phone: phoneTwo, email: emailThree },
|
||||
{ name: 'customer-g', phone: phoneTwo, email: emailThree },
|
||||
];
|
||||
|
||||
for (const { name, email, phone } of customers) {
|
||||
await db.insert('Customer', {
|
||||
name,
|
||||
email,
|
||||
phone,
|
||||
...getDefaultMetaFieldValueMap(),
|
||||
});
|
||||
}
|
||||
|
||||
// Get total count
|
||||
t.equal((await db.getAll('Customer')).length, customers.length);
|
||||
|
||||
// Single filter
|
||||
t.equal(
|
||||
await db.deleteAll('Customer', { email: emailOne }),
|
||||
customers.filter((c) => c.email === emailOne).length
|
||||
);
|
||||
t.equal(
|
||||
(await db.getAll('Customer', { filters: { email: emailOne } })).length,
|
||||
0
|
||||
);
|
||||
|
||||
// Multiple filters
|
||||
t.equal(
|
||||
await db.deleteAll('Customer', { email: emailTwo, phone: phoneTwo }),
|
||||
customers.filter(
|
||||
({ phone, email }) => email === emailTwo && phone === phoneTwo
|
||||
).length
|
||||
);
|
||||
t.equal(
|
||||
await db.deleteAll('Customer', { email: emailTwo, phone: phoneTwo }),
|
||||
0
|
||||
);
|
||||
|
||||
// Includes filters
|
||||
t.equal(
|
||||
await db.deleteAll('Customer', { email: ['in', [emailTwo, emailThree]] }),
|
||||
customers.filter(
|
||||
({ email, phone }) =>
|
||||
[emailTwo, emailThree].includes(email) &&
|
||||
!(phone === phoneTwo && email === emailTwo)
|
||||
).length
|
||||
);
|
||||
t.equal(
|
||||
(
|
||||
await db.getAll('Customer', {
|
||||
filters: { email: ['in', [emailTwo, emailThree]] },
|
||||
})
|
||||
).length,
|
||||
0
|
||||
);
|
||||
|
||||
await db.close();
|
||||
});
|
||||
|
@ -6,7 +6,12 @@ import Observable from 'fyo/utils/observable';
|
||||
import { translateSchema } from 'fyo/utils/translation';
|
||||
import { Field, RawValue, SchemaMap } from 'schemas/types';
|
||||
import { getMapFromList } from 'utils';
|
||||
import { DatabaseBase, DatabaseDemuxBase, GetAllOptions } from 'utils/db/types';
|
||||
import {
|
||||
DatabaseBase,
|
||||
DatabaseDemuxBase,
|
||||
GetAllOptions,
|
||||
QueryFilter,
|
||||
} from 'utils/db/types';
|
||||
import { schemaTranslateables } from 'utils/translationHelpers';
|
||||
import { LanguageMap } from 'utils/types';
|
||||
import { Converter } from './converter';
|
||||
@ -207,6 +212,16 @@ export class DatabaseHandler extends DatabaseBase {
|
||||
this.observer.trigger(`delete:${schemaName}`, name);
|
||||
}
|
||||
|
||||
async deleteAll(schemaName: string, filters: QueryFilter): Promise<number> {
|
||||
const count = (await this.#demux.call(
|
||||
'deleteAll',
|
||||
schemaName,
|
||||
filters
|
||||
)) as number;
|
||||
this.observer.trigger(`deleteAll:${schemaName}`, filters);
|
||||
return count;
|
||||
}
|
||||
|
||||
// Other
|
||||
async exists(schemaName: string, name?: string): Promise<boolean> {
|
||||
const doesExist = (await this.#demux.call(
|
||||
|
@ -43,6 +43,8 @@ export abstract class DatabaseBase {
|
||||
|
||||
// Delete
|
||||
abstract delete(schemaName: string, name: string): Promise<void>;
|
||||
|
||||
abstract deleteAll(schemaName:string, filters:QueryFilter): Promise<number>;
|
||||
|
||||
// Other
|
||||
abstract close(): Promise<void>;
|
||||
|
Loading…
Reference in New Issue
Block a user