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
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
|
|
// // });
|
|
// // }
|
|
// // }));
|