Skip to content

Instantly share code, notes, and snippets.

@jmagnuss
Last active December 19, 2019 23:48
Show Gist options
  • Select an option

  • Save jmagnuss/419db1c4891b5aa7f79a40e4cf8e9a4a to your computer and use it in GitHub Desktop.

Select an option

Save jmagnuss/419db1c4891b5aa7f79a40e4cf8e9a4a to your computer and use it in GitHub Desktop.
// 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