2
0
mirror of https://github.com/frappe/books.git synced 2024-11-08 23:00:56 +00:00

incr: add error messaging

This commit is contained in:
18alantom 2022-03-31 14:34:30 +05:30
parent 804d841466
commit 4dbecad1cb
7 changed files with 214 additions and 18 deletions

View File

@ -1,20 +1,114 @@
import { DatabaseDemux } from '@/demux/db';
import { Frappe } from 'frappe/core/frappe';
import { DatabaseBase, GetAllOptions } from 'utils/db/types';
import { DocValueMap, RawValueMap } from './types';
type SingleValue = { fieldname: string; parent: string; value: unknown };
export class DatabaseHandler extends DatabaseBase {
#frappe: Frappe;
#demux: DatabaseDemux;
export class DbHandler {
frappe: Frappe;
constructor(frappe: Frappe) {
this.frappe = frappe;
super();
this.#frappe = frappe;
this.#demux = new DatabaseDemux(frappe.isElectron);
}
init() {}
close() {}
exists(doctype: string, name: string): boolean {
return false;
async createNewDatabase(dbPath: string, countryCode?: string) {
await this.#demux.createNewDatabase(dbPath, countryCode);
}
getSingleValues(...fieldnames: Omit<SingleValue, 'value'>[]): SingleValue[] {
return [];
async connectToDatabase(dbPath: string, countryCode?: string) {
await this.#demux.connectToDatabase(dbPath, countryCode);
}
init() {
// do nothing
}
async insert(
schemaName: string,
docValueMap: DocValueMap
): Promise<DocValueMap> {
let rawValueMap = this.toRawValueMap(
schemaName,
docValueMap
) as RawValueMap;
rawValueMap = (await this.#demux.call(
'insert',
schemaName,
rawValueMap
)) as RawValueMap;
return this.toDocValueMap(schemaName, rawValueMap) as DocValueMap;
}
// Read
async get(
schemaName: string,
name: string,
fields?: string | string[]
): Promise<DocValueMap> {
const rawValueMap = (await this.#demux.call(
'get',
schemaName,
name,
fields
)) as RawValueMap;
return this.toDocValueMap(schemaName, rawValueMap) as DocValueMap;
}
async getAll(
schemaName: string,
options: GetAllOptions
): Promise<DocValueMap[]> {
const rawValueMap = (await this.#demux.call(
'getAll',
schemaName,
options
)) as RawValueMap[];
return this.toDocValueMap(schemaName, rawValueMap) as DocValueMap[];
}
async getSingleValues(
...fieldnames: ({ fieldname: string; parent?: string } | string)[]
): Promise<{ fieldname: string; parent: string; value: unknown }[]> {
await this.#demux.call('getSingleValues', ...fieldnames);
}
// Update
async rename(
schemaName: string,
oldName: string,
newName: string
): Promise<void> {
await this.#demux.call('rename', schemaName, oldName, newName);
}
async update(schemaName: string, docValueMap: DocValueMap): Promise<void> {
const rawValueMap = this.toRawValueMap(schemaName, docValueMap);
await this.#demux.call('update', schemaName, rawValueMap);
}
// Delete
async delete(schemaName: string, name: string): Promise<void> {
await this.#demux.call('delete', schemaName, name);
}
// Other
async close(): Promise<void> {
await this.#demux.call('close');
}
async exists(schemaName: string, name?: string): Promise<boolean> {
return (await this.#demux.call('exists', schemaName, name)) as boolean;
}
toDocValueMap(
schemaName: string,
rawValueMap: RawValueMap | RawValueMap[]
): DocValueMap | DocValueMap[] {}
toRawValueMap(
schemaName: string,
docValueMap: DocValueMap | DocValueMap[]
): RawValueMap | RawValueMap[] {}
}

View File

@ -12,7 +12,7 @@ import * as errors from '../utils/errors';
import { format } from '../utils/format';
import { t, T } from '../utils/translation';
import { AuthHandler } from './authHandler';
import { DbHandler } from './dbHandler';
import { DatabaseHandler } from './dbHandler';
import { DocHandler } from './docHandler';
export class Frappe {
@ -28,7 +28,7 @@ export class Frappe {
auth: AuthHandler;
doc: DocHandler;
db: DbHandler;
db: DatabaseHandler;
Meta?: typeof Meta;
Document?: typeof Doc;
@ -42,7 +42,7 @@ export class Frappe {
constructor() {
this.auth = new AuthHandler(this);
this.doc = new DocHandler(this);
this.db = new DbHandler(this);
this.db = new DatabaseHandler(this);
this.pesa = getMoneyMaker({
currency: 'XXX',
precision: DEFAULT_INTERNAL_PRECISION,

7
frappe/core/types.ts Normal file
View File

@ -0,0 +1,7 @@
import Money from 'pesa/dist/types/src/money';
import { RawValue } from 'schemas/types';
export type DocValue = string | number | boolean | Date | Money;
export type DocValueMap = Record<string, DocValue | DocValueMap[]>;
export type RawValueMap = Record<string, RawValue | RawValueMap[]>;

View File

@ -8,6 +8,7 @@ import { getUrlAndTokenString, sendError } from '../src/contactMothership';
import { getLanguageMap } from '../src/getLanguageMap';
import saveHtmlAsPdf from '../src/saveHtmlAsPdf';
import { DatabaseMethod } from '../utils/db/types';
import { DatabaseResponse } from '../utils/ipc/types';
import { IPC_ACTIONS } from '../utils/messages';
import { getMainWindowSize } from './helpers';
@ -126,21 +127,48 @@ export default function registerIpcMainActionListeners(main: Main) {
ipcMain.handle(
IPC_ACTIONS.DB_CREATE,
async (_, dbPath: string, countryCode?: string) => {
return databaseManager.createNewDatabase(dbPath, countryCode);
const response: DatabaseResponse = { error: '', data: undefined };
try {
response.data = await databaseManager.createNewDatabase(
dbPath,
countryCode
);
} catch (error) {
response.error = error.toString();
}
return response;
}
);
ipcMain.handle(
IPC_ACTIONS.DB_CONNECT,
async (_, dbPath: string, countryCode?: string) => {
return databaseManager.createNewDatabase(dbPath, countryCode);
const response: DatabaseResponse = { error: '', data: undefined };
try {
response.data = await databaseManager.createNewDatabase(
dbPath,
countryCode
);
} catch (error) {
response.error = error.toString();
}
return response;
}
);
ipcMain.handle(
IPC_ACTIONS.DB_CALL,
async (_, method: DatabaseMethod, ...args: unknown[]) => {
return databaseManager.call(method, ...args);
const response: DatabaseResponse = { error: '', data: undefined };
try {
response.data = await databaseManager.call(method, ...args);
} catch (error) {
response.error = error.toString();
}
return response;
}
);
}

View File

@ -56,9 +56,9 @@ export enum FieldTypeEnum {
}
export type FieldType = keyof typeof FieldTypeEnum;
export type RawValue = string | number | boolean;
export type RawValue = string | number | boolean | null;
// @formatter:off
// prettier-ignore
export interface BaseField {
fieldname: string; // Column name in the db
fieldtype: FieldType; // UI Descriptive field types that map to column types

63
src/demux/db.ts Normal file
View File

@ -0,0 +1,63 @@
import { ipcRenderer } from 'electron';
import { DatabaseMethod } from 'utils/db/types';
import { IPC_ACTIONS } from 'utils/messages';
import { DatabaseResponse } from '../../utils/ipc/types';
export class DatabaseDemux {
#isElectron: boolean = false;
constructor(isElectron: boolean) {
this.#isElectron = isElectron;
}
async createNewDatabase(dbPath: string, countryCode?: string): Promise<void> {
let response: DatabaseResponse;
if (this.#isElectron) {
response = await ipcRenderer.invoke(
IPC_ACTIONS.DB_CREATE,
dbPath,
countryCode
);
} else {
// TODO: API Call
response = { error: '', data: undefined };
}
if (response.error) {
throw new Error(response.error);
}
}
async connectToDatabase(dbPath: string, countryCode?: string): Promise<void> {
let response: DatabaseResponse;
if (this.#isElectron) {
response = await ipcRenderer.invoke(
IPC_ACTIONS.DB_CONNECT,
dbPath,
countryCode
);
} else {
// TODO: API Call
response = { error: '', data: undefined };
}
if (response.error) {
throw new Error(response.error);
}
}
async call(method: DatabaseMethod, ...args: unknown[]): Promise<unknown> {
let response: DatabaseResponse;
if (this.#isElectron) {
response = await ipcRenderer.invoke(IPC_ACTIONS.DB_CALL, method, ...args);
} else {
// TODO: API Call
response = { error: '', data: undefined };
}
if (response.error) {
throw new Error(response.error);
}
return response.data;
}
}

4
utils/ipc/types.ts Normal file
View File

@ -0,0 +1,4 @@
export interface DatabaseResponse {
error: string;
data?: unknown;
}