public compress()

in sqlite/src/compress.ts [203:330]


	public compress(element: T, options: CompressorOptions, level: number = 0): CompressValue {
		let result: CompressArray = this._parent !== undefined ? this._parent.compress(element, options, level + 1) as CompressArray: [];
		if (level === 0) {
			result.unshift(options.mode === 'store' ? this._id : -1);
		}
		let undefinedElements: number = 0;
		const recordUndefined = () => {
			undefinedElements++;
		};
		const pushUndefined = () => {
			for (let i = 0; i < undefinedElements; i++) {
				result.push(undefined);
			}
			undefinedElements = 0;
		};
		function getCompressor(value: Compressor<any> | ((value: any) => Compressor<any> | undefined) | undefined, prop: any, force: true): Compressor<any>;
		function getCompressor(value: Compressor<any> | ((value: any) => Compressor<any> | undefined) | undefined, prop: any, force?: boolean): Compressor<any> | undefined;
		function getCompressor(value: Compressor<any> | ((value: any) => Compressor<any> | undefined) | undefined, prop: any, force: boolean = false): Compressor<any> | undefined {
			if (value instanceof Compressor) {
				return value;
			}
			if (value === undefined) {
				if (force === true) {
					throw new Error('No compressor available');
				} else {
					return undefined;
				}
			}
			return value(prop);
		}

		for (let item of this._properties) {
			let value = element[item.name];
			if (value === undefined || value === null) {
				recordUndefined();
				continue;
			}
			switch (item.compressionKind) {
				case CompressionKind.id:
					pushUndefined();
					if (typeof options.idTransformer === 'function') {
						result.push(options.idTransformer(value as any));
					} else {
						result.push(value as any);
					}
					break;
				case CompressionKind.ids: {
					if (!Array.isArray(value)) {
						throw new Error('Type mismatch. Compressor property declares array but value is not an array');
					}
					pushUndefined();
					if (typeof options.idTransformer === 'function') {
						const convertedIds: Id[] = [];
						for (const element of value) {
							convertedIds.push(options.idTransformer(element));
						}
						result.push(convertedIds);
					} else {
						result.push(value);
					}
					break;
				}
				case CompressionKind.raw:
					pushUndefined();
					result.push(value as unknown as CompressValue);
					break;
				case CompressionKind.scalar:
					let convertedScalar: any = value;
					if (item.shortForm !== undefined && Is.string(value)) {
						const short = item.shortForm.get(value);
						if (short !== undefined) {
							convertedScalar = short;
						}
					}
					pushUndefined();
					result.push(convertedScalar as CompressValue);
					break;
				case CompressionKind.literal:
					const c1 = getCompressor(item.compressor, value, true);
					pushUndefined();
					result.push(c1.compress(value, options));
					break;
				case CompressionKind.array:
					if (!Array.isArray(value)) {
						throw new Error('Type mismatch. Compressor property declares array but value is not an array');
					}
					const convertedArray: any[] = [];
					for (const element of value) {
						const c2 = getCompressor(item.compressor, element, false);
						if (c2 !== undefined) {
							convertedArray.push(c2.compress(element, options));
						} else {
							convertedArray.push(element);
						}
					}
					pushUndefined();
					result.push(convertedArray);
					break;
				case CompressionKind.any:
					const handleValue = (value: any): any => {
						const compressor = getCompressor(item.compressor, value, false);
						if (compressor !== undefined) {
							return compressor.compress(value, options);
						}
						const type = typeof value;
						if (type === 'number' || type === 'string' || type === 'boolean') {
							return value;
						}
						throw new Error(`Any compression kind can't infer conversion for property ${item.name}`);
					};
					let convertedAny: any;
					if (Array.isArray(value)) {
						convertedAny = [];
						for (const element of value) {
							(convertedAny as any[]).push(handleValue(element));
						}
					} else {
						convertedAny = handleValue(value);
					}
					pushUndefined();
					result.push(convertedAny);
					break;
				default:
					throw new Error(`Compression kind ${item.compressionKind} unknown.`);
			}
		}
		return result;
	}