Last active
December 19, 2019 23:48
-
-
Save jmagnuss/419db1c4891b5aa7f79a40e4cf8e9a4a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // IonObjectConverter.ts | |
| import { Reader, IonType, IonTypes } from "ion-js"; | |
| /** | |
| * IonObjectConverter | |
| * Helper module to take Ion results (QLDB query records) and output Javascript / TS objects for use in | |
| * your code / REST API. | |
| * | |
| * See notes here: https://amzn.github.io/ion-docs/guides/cookbook.html#down-converting-to-json | |
| * and Issue here: https://github.com/amzn/ion-js/issues/531 | |
| * | |
| * Usage example: | |
| * | |
| * private resultsToObjects(resultList: Reader[]): Array<IonRecordMap> { | |
| * let results: IonRecordMap[] = new Array(); | |
| * resultList.forEach((reader: Reader) => { | |
| * let result: IonRecordMap = convertIonRecord(reader); | |
| * results.push(result); | |
| * }); | |
| * return results; | |
| * } | |
| * | |
| */ | |
| export type IonRecordMap = Map<string, any>; | |
| /** | |
| * convertIonRecord | |
| * | |
| * Pass in an Ion Reader value pointing to a result, and it wil recursively create an Object with the Ion | |
| * values. | |
| * | |
| * @param reader | |
| */ | |
| export function convertIonRecord(reader: Reader): any { | |
| // Assuming at the top level we have a struct, representing the Ion record. | |
| // The ionly other time we begin this function is when we recurse to a list/sexp/struct | |
| const result: IonRecordMap = new Map<string,any>(); | |
| reader.next(); // advance from "beginning of structure" to the structure itself | |
| reader.stepIn(); // enter our structure / list | |
| let type: IonType | null = null; | |
| while ((type = reader.next()) !== null) { | |
| if (reader.fieldName() === null) { | |
| throw Error("Null field name"); | |
| return undefined; | |
| } | |
| const fieldName: string = reader.fieldName()!; | |
| let value: any = undefined; | |
| // Do we need to recur? | |
| if (type.isContainer) { | |
| reader.stepIn(); | |
| value = convertIonRecord(reader); | |
| reader.stepOut(); | |
| } | |
| // If scalar value, fetch it properly | |
| switch (type) { | |
| case IonTypes.NULL: | |
| value = null; | |
| break; | |
| case IonTypes.BOOL: | |
| value = reader.booleanValue(); | |
| break; | |
| case IonTypes.DECIMAL: | |
| case IonTypes.FLOAT: | |
| case IonTypes.INT: | |
| value = reader.numberValue(); | |
| break; | |
| case IonTypes.TIMESTAMP: | |
| break; | |
| case IonTypes.SYMBOL: | |
| case IonTypes.STRING: | |
| value = reader.stringValue(); | |
| break; | |
| case IonTypes.CLOB: | |
| case IonTypes.BLOB: | |
| throw Error("Unhandled Ion type: " + type.name); | |
| // TODO | |
| break; | |
| case IonTypes.LIST: | |
| case IonTypes.SEXP: | |
| case IonTypes.STRUCT: | |
| // Handled above in the recursion function call, do nothing | |
| break; | |
| default: | |
| throw Error("Unhandled Ion type: " + type.name); | |
| }; | |
| // Set the field we've been looking at in our result structure | |
| result.set(fieldName, value); | |
| } // end of while loop on next() - should be end of our structure/list | |
| reader.stepOut(); | |
| return result; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment