You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.2 KiB
JavaScript

"use strict";
const assert = require("assert");
const timeCall = require("time-call");
const encodeField = require("./encode-field");
const coders = require("./coders");
// TODO: Test if codegen can speed this up, though note that dynamically-created functions execute in global scope *only*
// TODO: Enum
// FIXME: Default field values
// FIXME:regex type
module.exports = function createRecordObjectCoder(schema) {
return {
encode: function (object) {
let auxiliaryBlobs = new Map();
let buffers = schema.flatMap(({ name, type: fieldType, required, attributes }) => {
// options = { precision, withTimezone, signed, ... }
let value = object[name];
let result = encodeField({ asIndexKey: false, name, value, fieldType, required, ... attributes });
if (result.auxiliaryBlob !== undefined) {
auxiliaryBlobs.set(result.auxiliaryBlob.key, result.auxiliaryBlob.value);
}
return result.value;
});
return {
record: Buffer.concat(buffers),
auxiliaryBlobs: auxiliaryBlobs
};
},
decode: function (buffer) {
let offset = 0;
let resultObject = {};
schema.forEach(({ name, type: fieldType, attributes }) => {
let result = coders.decode(fieldType, buffer, offset, attributes);
if (result.auxiliaryBlob === undefined) {
resultObject[name] = result.value;
} else {
// FIXME
resultObject[name] = { _blobKey: result.auxiliaryBlob.key };
}
offset += result.bytesRead;
});
// Ensure that we've read exactly enough bytes
assert(offset === buffer.length);
return resultObject;
}
};
};
// let dummySchema = [
// { name: "username", type: "string", required: true },
// { name: "passwordHash", type: "string", required: true },
// { name: "emailAddress", type: "string" },
// { name: "isActive", type: "boolean", required: true },
// { name: "registrationDate", type: "date", required: true, attributes: { withTimezone: true } },
// { name: "invitesLeft", type: "integer", required: true },
// ];
// let recordCoder = module.exports(dummySchema);
// let input = {
// username: "joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91joepie91",
// passwordHash: "foobar",
// emailAddress: "admin@cryto.net",
// isActive: true,
// registrationDate: new Date,
// invitesLeft: 10
// };
// let encoded = recordCoder.encode(input);
// let decoded = recordCoder.decode(encoded.record);
// // 44 bytes encoded
// // 29 characters string
// // 15 bytes extra
// console.log({ input, encoded, decoded });
// // console.log(timeCall(() => {
// // for (let i = 0; i < 1000; i++) {
// // recordCoder.encode({
// // username: "joepie91",
// // passwordHash: "foobar",
// // emailAddress: "admin@cryto.net",
// // isActive: true,
// // registrationDate: new Date,
// // invitesLeft: 10
// // });
// // }
// // }));