Skip to content

Commit

Permalink
feat: do not use/export enums (#274)
Browse files Browse the repository at this point in the history
BREAKING CHANGE:  `ColumnType` is not a TypeScript enum anymore:
- `ColumnType` is a union type
- `ColumnTypes` a map for easier usage of `ColumnType`
  • Loading branch information
andipaetzold committed Feb 4, 2023
1 parent 84a968b commit ce27203
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 111 deletions.
7 changes: 7 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
"caughtErrorsIgnorePattern": "^_"
}
],
"no-restricted-syntax": [
"error",
{
"selector": "TSEnumDeclaration:not([const=true])",
"message": "Do not use enums"
}
],
"no-restricted-imports": [
"error",
"assert",
Expand Down
2 changes: 1 addition & 1 deletion src/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { CodecHandler, createCodecHandler } from "./codec-handler/index.js";
import { decryptRC4 } from "./crypto/index.js";
import { readDateTime } from "./data/datetime.js";
import { getJetFormat, JetFormat } from "./JetFormat/index.js";
import PageType, { assertPageType } from "./PageType.js";
import { PageType, assertPageType } from "./PageType.js";
import { SortOrder } from "./types.js";
import { uncompressText } from "./unicodeCompression.js";
import { isEmptyBuffer, xor } from "./util.js";
Expand Down
10 changes: 5 additions & 5 deletions src/MDBReader.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Database from "./Database.js";
import PageType, { assertPageType } from "./PageType.js";
import SysObject, { isSysObjectType, isSystemObject, SysObjectType } from "./SysObject.js";
import { PageType, assertPageType } from "./PageType.js";
import { SysObject, isSysObjectType, isSystemObject, SysObjectTypes } from "./SysObject.js";
import Table from "./Table.js";
import { SortOrder } from "./types.js";

Expand Down Expand Up @@ -84,15 +84,15 @@ export default class MDBReader {
): string[] {
const filteredSysObjects: SysObject[] = [];
for (const sysObject of this.sysObjects) {
if (sysObject.objectType === SysObjectType.Table) {
if (sysObject.objectType === SysObjectTypes.Table) {
if (!isSystemObject(sysObject)) {
if (normalTables) {
filteredSysObjects.push(sysObject);
}
} else if (systemTables) {
filteredSysObjects.push(sysObject);
}
} else if (sysObject.objectType === SysObjectType.LinkedTable && linkedTables) {
} else if (sysObject.objectType === SysObjectTypes.LinkedTable && linkedTables) {
filteredSysObjects.push(sysObject);
}
}
Expand All @@ -107,7 +107,7 @@ export default class MDBReader {
*/
public getTable(name: string): Table {
const sysObject = this.sysObjects
.filter((o) => o.objectType === SysObjectType.Table)
.filter((o) => o.objectType === SysObjectTypes.Table)
.find((o) => o.objectName === name);

if (!sysObject) {
Expand Down
4 changes: 1 addition & 3 deletions src/PageType.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @see https://github.com/brianb/mdbtools/blob/d6f5745d949f37db969d5f424e69b54f0da60b9b/HACKING#L64-L70
*/
enum PageType {
export const enum PageType {
DatabaseDefinitionPage = 0x00,
DataPage = 0x01,
TableDefinition = 0x02,
Expand All @@ -10,8 +10,6 @@ enum PageType {
PageUsageBitmaps = 0x05,
}

export default PageType;

export function assertPageType(buffer: Buffer, pageType: PageType): void {
if (buffer[0] !== pageType) {
throw new Error(`Wrong page type. Expected ${pageType} but received ${buffer[0]}.`);
Expand Down
44 changes: 23 additions & 21 deletions src/SysObject.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
export default interface SysObject {
/**
* @see https://github.com/brianb/mdbtools/blob/d6f5745d949f37db969d5f424e69b54f0da60b9b/include/mdbtools.h#L73-L87
*/
export const SysObjectTypes = {
Form: 0x00,
Table: 0x01,
Macro: 0x02,
SystemTable: 0x03,
Report: 0x04,
Query: 0x05,
LinkedTable: 0x06,
Module: 0x07,
Relationship: 0x08,
DatabaseProperty: 0x0b,
} satisfies Record<string, number>;

export type SysObjectType = typeof SysObjectTypes[keyof typeof SysObjectTypes];

export function isSysObjectType(typeValue: number): boolean {
return Object.values(SysObjectTypes).includes(typeValue);
}

export interface SysObject {
objectName: string;

/**
Expand All @@ -9,26 +31,6 @@ export default interface SysObject {
flags: number;
}

/**
* @see https://github.com/brianb/mdbtools/blob/d6f5745d949f37db969d5f424e69b54f0da60b9b/include/mdbtools.h#L73-L87
*/
export enum SysObjectType {
Form = 0x00,
Table = 0x01,
Macro = 0x02,
SystemTable = 0x03,
Report = 0x04,
Query = 0x05,
LinkedTable = 0x06,
Module = 0x07,
Relationship = 0x08,
DatabaseProperty = 0x0b,
}

export function isSysObjectType(typeValue: number): typeValue is SysObjectType {
return Object.values(SysObjectType).includes(typeValue);
}

const SYSTEM_OBJECT_FLAG = 0x80000000;
const ALT_SYSTEM_OBJECT_FLAG = 0x02;
const SYSTEM_OBJECT_FLAGS = SYSTEM_OBJECT_FLAG | ALT_SYSTEM_OBJECT_FLAG;
Expand Down
10 changes: 5 additions & 5 deletions src/Table.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ColumnType } from "./index.js";
import { ColumnTypes } from "./index.js";
import { Column, ColumnDefinition, getColumnType, parseColumnFlags } from "./column.js";
import { readFieldValue } from "./data/index.js";
import Database from "./Database.js";
import PageType, { assertPageType } from "./PageType.js";
import { PageType, assertPageType } from "./PageType.js";
import { Value } from "./types.js";
import { uncompressText } from "./unicodeCompression.js";
import { findMapPages } from "./usage-map.js";
Expand Down Expand Up @@ -147,7 +147,7 @@ export default class Table {
this.db.format.tableDefinitionPage.columnsDefinition.variableIndexOffset
),
size:
type === ColumnType.Boolean
type === ColumnTypes.Boolean
? 0
: columnBuffer.readUInt16LE(this.db.format.tableDefinitionPage.columnsDefinition.sizeOffset),
fixedIndex: columnBuffer.readUInt16LE(this.db.format.tableDefinitionPage.columnsDefinition.fixedIndexOffset),
Expand All @@ -156,7 +156,7 @@ export default class Table {
),
};

if (type === ColumnType.Numeric) {
if (type === ColumnTypes.Numeric) {
column.precision = columnBuffer.readUInt8(11);
column.scale = columnBuffer.readUInt8(12);
}
Expand Down Expand Up @@ -352,7 +352,7 @@ export default class Table {
size = 0;
}

if (column.type === ColumnType.Boolean) {
if (column.type === ColumnTypes.Boolean) {
value = value === undefined;
} else if (value !== null) {
value = readFieldValue(pageBuffer.slice(start, start + size), column, this.db);
Expand Down
38 changes: 19 additions & 19 deletions src/column.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ColumnType } from "./types.js";
import { ColumnType, ColumnTypes } from "./types.js";

export interface Column {
/**
Expand Down Expand Up @@ -37,24 +37,24 @@ export interface ColumnDefinition extends Column {
fixedIndex: number;
}

const columnTypeMap: { [v: number]: ColumnType } = {
0x01: ColumnType.Boolean,
0x02: ColumnType.Byte,
0x03: ColumnType.Integer,
0x04: ColumnType.Long,
0x05: ColumnType.Currency,
0x06: ColumnType.Float,
0x07: ColumnType.Double,
0x08: ColumnType.DateTime,
0x09: ColumnType.Binary,
0x0a: ColumnType.Text,
0x0b: ColumnType.Long,
0x0c: ColumnType.Memo,
0x0f: ColumnType.RepID,
0x10: ColumnType.Numeric,
0x12: ColumnType.Complex,
0x13: ColumnType.BigInt,
0x14: ColumnType.DateTimeExtended,
const columnTypeMap: Record<number, ColumnType> = {
0x01: ColumnTypes.Boolean,
0x02: ColumnTypes.Byte,
0x03: ColumnTypes.Integer,
0x04: ColumnTypes.Long,
0x05: ColumnTypes.Currency,
0x06: ColumnTypes.Float,
0x07: ColumnTypes.Double,
0x08: ColumnTypes.DateTime,
0x09: ColumnTypes.Binary,
0x0a: ColumnTypes.Text,
0x0b: ColumnTypes.Long,
0x0c: ColumnTypes.Memo,
0x0f: ColumnTypes.RepID,
0x10: ColumnTypes.Numeric,
0x12: ColumnTypes.Complex,
0x13: ColumnTypes.BigInt,
0x14: ColumnTypes.DateTimeExtended,
};

/**
Expand Down
38 changes: 19 additions & 19 deletions src/data/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Column, ColumnDefinition } from "../column.js";
import Database from "../Database.js";
import { ColumnType, Value, ValueMap } from "../types.js";
import { ColumnType, ColumnTypes, Value, ValueMap } from "../types.js";
import { readBigInt } from "./bigint.js";
import { readBinary } from "./binary.js";
import { readByte } from "./byte.js";
Expand All @@ -18,30 +18,30 @@ import { readRepID } from "./repid.js";
import { readText } from "./text.js";

const readFnByColType: {
[type in Exclude<ColumnType, ColumnType.Boolean>]:
[type in Exclude<ColumnType, typeof ColumnTypes.Boolean>]:
| ((buffer: Buffer, column: Column, database: Database) => ValueMap[type])
| undefined;
} = {
[ColumnType.BigInt]: readBigInt,
[ColumnType.Binary]: readBinary,
[ColumnType.Byte]: readByte,
[ColumnType.Complex]: readComplexOrLong,
[ColumnType.Currency]: readCurrency,
[ColumnType.DateTime]: readDateTime,
[ColumnType.DateTimeExtended]: readDateTimeExtended,
[ColumnType.Double]: readDouble,
[ColumnType.Float]: readFloat,
[ColumnType.Integer]: readInteger,
[ColumnType.Long]: readComplexOrLong,
[ColumnType.Text]: readText,
[ColumnType.Memo]: readMemo,
[ColumnType.Numeric]: readNumeric,
[ColumnType.OLE]: readOLE,
[ColumnType.RepID]: readRepID,
[ColumnTypes.BigInt]: readBigInt,
[ColumnTypes.Binary]: readBinary,
[ColumnTypes.Byte]: readByte,
[ColumnTypes.Complex]: readComplexOrLong,
[ColumnTypes.Currency]: readCurrency,
[ColumnTypes.DateTime]: readDateTime,
[ColumnTypes.DateTimeExtended]: readDateTimeExtended,
[ColumnTypes.Double]: readDouble,
[ColumnTypes.Float]: readFloat,
[ColumnTypes.Integer]: readInteger,
[ColumnTypes.Long]: readComplexOrLong,
[ColumnTypes.Text]: readText,
[ColumnTypes.Memo]: readMemo,
[ColumnTypes.Numeric]: readNumeric,
[ColumnTypes.OLE]: readOLE,
[ColumnTypes.RepID]: readRepID,
};

export function readFieldValue(buffer: Buffer, column: ColumnDefinition, db: Database): Value | undefined {
if (column.type === ColumnType.Boolean) {
if (column.type === ColumnTypes.Boolean) {
throw new Error("readFieldValue does not handle type boolean");
}

Expand Down
76 changes: 39 additions & 37 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,46 @@
export enum ColumnType {
Boolean = "boolean",
Byte = "byte",
Integer = "integer",
Long = "long",
Currency = "currency",
Float = "float",
Double = "double",
DateTime = "datetime",
Binary = "binary",
Text = "text",
OLE = "ole",
Memo = "memo",
RepID = "repid",
Numeric = "numeric",
Complex = "complex",
BigInt = "bigint",
DateTimeExtended = "datetimextended",
}
export const ColumnTypes = {
Boolean: "boolean",
Byte: "byte",
Integer: "integer",
Long: "long",
Currency: "currency",
Float: "float",
Double: "double",
DateTime: "datetime",
Binary: "binary",
Text: "text",
OLE: "ole",
Memo: "memo",
RepID: "repid",
Numeric: "numeric",
Complex: "complex",
BigInt: "bigint",
DateTimeExtended: "datetimextended",
} as const;

export type ColumnType = typeof ColumnTypes[keyof typeof ColumnTypes];

export type ValueMap = {
[ColumnType.Binary]: Buffer;
[ColumnType.BigInt]: bigint;
[ColumnType.Boolean]: boolean;
[ColumnType.Byte]: number;
[ColumnType.Complex]: number;
[ColumnType.Currency]: string;
[ColumnType.DateTime]: Date;
[ColumnType.DateTimeExtended]: string;
[ColumnType.Double]: number;
[ColumnType.Float]: number;
[ColumnType.Integer]: number;
[ColumnType.Long]: number;
[ColumnType.Memo]: string;
[ColumnType.Numeric]: string;
[ColumnType.OLE]: Buffer;
[ColumnType.RepID]: string;
[ColumnType.Text]: string;
[ColumnTypes.Binary]: Buffer;
[ColumnTypes.BigInt]: bigint;
[ColumnTypes.Boolean]: boolean;
[ColumnTypes.Byte]: number;
[ColumnTypes.Complex]: number;
[ColumnTypes.Currency]: string;
[ColumnTypes.DateTime]: Date;
[ColumnTypes.DateTimeExtended]: string;
[ColumnTypes.Double]: number;
[ColumnTypes.Float]: number;
[ColumnTypes.Integer]: number;
[ColumnTypes.Long]: number;
[ColumnTypes.Memo]: string;
[ColumnTypes.Numeric]: string;
[ColumnTypes.OLE]: Buffer;
[ColumnTypes.RepID]: string;
[ColumnTypes.Text]: string;
};

export type Value = ValueMap[ColumnType] | null;
export type Value = ValueMap[keyof ValueMap] | null;

export interface SortOrder {
value: number;
Expand Down
2 changes: 1 addition & 1 deletion src/usage-map.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getBitmapValue } from "./util.js";
import Database from "./Database.js";
import PageType, { assertPageType } from "./PageType.js";
import { PageType, assertPageType } from "./PageType.js";

/**
* @see https://github.com/brianb/mdbtools/blob/d6f5745d949f37db969d5f424e69b54f0da60b9b/HACKING#L556-L622
Expand Down

0 comments on commit ce27203

Please sign in to comment.