Skip to content

Commit

Permalink
✨ Add Field.Decimal and Field.FixedDecimal fields
Browse files Browse the repository at this point in the history
  • Loading branch information
skerit committed Oct 29, 2023
1 parent 8f0e898 commit 06906b6
Show file tree
Hide file tree
Showing 7 changed files with 390 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Add `castToBigInt` and `convertBigIntForDatasource` to `Datasource` class
* Add `LocalDateTime`, `LocalDate` and `LocalTime` fields
* Make `TaskSchedules#startFromMenu()` return the started instance
* Add `Field.Decimal` and `Field.FixedDecimal` fields

## 1.3.19 (2023-10-18)

Expand Down
50 changes: 49 additions & 1 deletion lib/app/datasource/mongo_datasource.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Mongo.setMethod(function castToBigInt(value) {
*
* @return {Mongo.Long}
*/
Datasource.setMethod(function convertBigIntForDatasource(value) {
Mongo.setMethod(function convertBigIntForDatasource(value) {

if (value == null) {
return value;
Expand All @@ -147,6 +147,54 @@ Datasource.setMethod(function convertBigIntForDatasource(value) {
return mongo.Long.fromBigInt(value);
});

/**
* Convert the given value to a Decimal (for use in JS)
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*
* @param {*} value
*
* @return {BigInt}
*/
Mongo.setMethod(function castToDecimal(value) {

if (value == null) {
return value;
}

if (typeof value == 'object') {
value = value.toString();
}

return new Blast.Classes.Develry.Decimal(value);
});

/**
* Convert the given decimal for use in DB
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*
* @param {Decimal|String} value
*
* @return {Mongo.Decimal128}
*/
Mongo.setMethod(function convertDecimalForDatasource(value) {

if (value == null) {
return value;
}

if (!(value instanceof Blast.Classes.Develry.Decimal)) {
value = new Blast.Classes.Develry.Decimal(value);
}

return mongo.Decimal128.fromString(value.toString());
});

/**
* Get find options for the MongoDB server
*
Expand Down
105 changes: 105 additions & 0 deletions lib/app/helper_field/20-decimal_field.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/**
* The Decimal Field class
*
* @constructor
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*/
const DecimalField = Function.inherits('Alchemy.Field.Number', 'DecimalField');

/**
* Cast the given value to this field's type
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*
* @param {Mixed} value
*
* @return {Decimal}
*/
DecimalField.setMethod(function cast(value) {

// Allow null
if (value == null) {
return value;
}

if (value instanceof Classes.Develry.Decimal) {
value = value.toImmutable();
} else {
value = new Classes.Develry.Decimal(value);
}

return value;
});

/**
* Cast the given value to this field's type for search in a db
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*
* @param {Mixed} value
* @param {Array} field_paths The path to the field
*
* @return {Mixed}
*/
DecimalField.setMethod(function _castCondition(value, field_paths) {

if (value == null) {
return value;
}

value = this.cast(value);
value = this.datasource.convertDecimalForDatasource(value);

return value;
});

/**
* Prepare the value to be stored in the database
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*
* @param {Mixed} value The field's own value
* @param {Object} data The main record
* @param {Datasource} datasource The datasource instance
*
* @return {Mixed}
*/
DecimalField.setMethod(function _toDatasource(value, data, datasource, callback) {

value = this.cast(value);
value = this.datasource.convertDecimalForDatasource(value);

Blast.nextTick(() => callback(null, value));
});

/**
* Convert from database to app
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*
* @param {Object} query The original query
* @param {Object} options The original query options
* @param {Mixed} value The field value, as stored in the DB
* @param {Function} callback
*/
DecimalField.setMethod(function _toApp(query, options, value, callback) {

if (value && typeof value == 'object') {
value = value.toString();
}

value = this.cast(value);

callback(null, value);
});
44 changes: 44 additions & 0 deletions lib/app/helper_field/fixed_decimal_field.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* The FixedDecimal Field class
*
* @constructor
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*/
const FixedDecimalField = Function.inherits('Alchemy.Field.DecimalField', function FixedDecimalField(schema, name, options) {

if (options?.scale == null) {
throw new Error('FixedDecimal fields require a scale option');
}

FixedDecimalField.super.call(this, schema, name, options);
});

/**
* Cast the given value to this field's type
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*
* @param {Mixed} value
*
* @return {Decimal}
*/
FixedDecimalField.setMethod(function cast(value) {

// Allow null
if (value == null) {
return value;
}

if (value instanceof Classes.Develry.Decimal) {
value = value.toImmutable().toScale(this.options.scale);
} else {
value = new Classes.Develry.FixedDecimal(value, this.options.scale);
}

return value;
});
50 changes: 50 additions & 0 deletions lib/class/datasource.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ Datasource.setMethod(function allows(name) {
* @return {BigInt}
*/
Datasource.setMethod(function castToBigInt(value) {

if (value == null) {
return value;
}

return BigInt(value);
});

Expand All @@ -143,9 +148,54 @@ Datasource.setMethod(function castToBigInt(value) {
* @return {BigInt}
*/
Datasource.setMethod(function convertBigIntForDatasource(value) {

if (value == null) {
return value;
}

return BigInt(value);
});

/**
* Convert the given value to a Decimal (for use in JS)
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*
* @param {*} value
*
* @return {BigInt}
*/
Datasource.setMethod(function castToDecimal(value) {

if (value == null) {
return value;
}

return new Blast.Classes.Develry.Decimal(value);
});

/**
* Convert the given decimal for use in DB
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 1.3.20
* @version 1.3.20
*
* @param {Decimal|String} value
*
* @return {Decimal}
*/
Datasource.setMethod(function convertDecimalForDatasource(value) {

if (value == null) {
return value;
}

return new Blast.Classes.Develry.Decimal(value);
});

/**
* Hash a string synchronously
*
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"mongodb" : "~6.1.0",
"ncp" : "~2.0.0",
"postcss" : "~8.4.31",
"protoblast" : "~0.8.12",
"protoblast" : "~0.8.14",
"semver" : "~7.5.4",
"socket.io" : "~4.7.2",
"@11ways/socket.io-stream" : "~0.9.2",
Expand Down
Loading

0 comments on commit 06906b6

Please sign in to comment.