Skip to content

Commit

Permalink
feat: implement ole columns
Browse files Browse the repository at this point in the history
  • Loading branch information
andipaetzold committed Jul 15, 2020
1 parent e183790 commit 22dcaaf
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export function readFieldValue(
return readCurrency(buffer);
case "memo":
return readMemo(buffer, db);
case "ole":
return readOLE(buffer, db);
default:
return `Column type ${column.type} is currently not supported`;
}
Expand Down Expand Up @@ -145,3 +147,49 @@ function readMemo(buffer: Buffer, db: Database): string {
throw new Error(`Unknown memo type ${bitmask}`);
}
}

/**
* @see https://github.com/brianb/mdbtools/blob/d6f5745d949f37db969d5f424e69b54f0da60b9b/src/libmdb/data.c#L626-L688
*/
function readOLE(buffer: Buffer, db: Database): Buffer {
const memoLength = buffer.readUIntLE(0, 3);

const bitmask = buffer.readUInt8(3);

if (bitmask & 0x80) {
// inline
return buffer.slice(12, 12 + memoLength);
} else if (bitmask & 0x40) {
// single page
const pageRow = buffer.readUInt32LE(4);
const rowBuffer = db.findPageRow(pageRow);
return rowBuffer.slice(0, memoLength);
} else if (bitmask === 0) {
// multi page
let pageRow = buffer.readInt32LE(4);

let memoDataBuffer = Buffer.alloc(0);
do {
const rowBuffer = db.findPageRow(pageRow);

if (memoDataBuffer.length + rowBuffer.length - 4 > memoLength) {
break;
}

if (rowBuffer.length === 0) {
break;
}

memoDataBuffer = Buffer.concat([
memoDataBuffer,
rowBuffer.slice(4, buffer.length),
]);

pageRow = rowBuffer.readUInt32LE(0);
} while (pageRow !== 0);

return memoDataBuffer.slice(0, memoLength);
} else {
throw new Error(`Unknown memo type ${bitmask}`);
}
}
Binary file added test/data/V2007/ole.accdb
Binary file not shown.
17 changes: 17 additions & 0 deletions test/ole.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { readFileSync } from "fs";
import MDBReader, { Table } from "../src";
import { resolve } from "path";

let table: Table;

beforeEach(() => {
const path = resolve(__dirname, "data", "V2007", "ole.accdb");
const buffer = readFileSync(path);
const reader = new MDBReader(buffer);
table = reader.getTable("Table1");
});

it("reads ole data ", () => {
const rows = table.getData();
// TODO: check for correct values
});

0 comments on commit 22dcaaf

Please sign in to comment.