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:
parent
804d841466
commit
4dbecad1cb
@ -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[] {}
|
||||
}
|
||||
|
@ -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
7
frappe/core/types.ts
Normal 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[]>;
|
@ -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;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -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
63
src/demux/db.ts
Normal 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
4
utils/ipc/types.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export interface DatabaseResponse {
|
||||
error: string;
|
||||
data?: unknown;
|
||||
}
|
Loading…
Reference in New Issue
Block a user