Skip to content

Commit

Permalink
Adding date casting support
Browse files Browse the repository at this point in the history
  • Loading branch information
theianjohnson committed Nov 23, 2023
1 parent 830a3f2 commit 788ef68
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 22 deletions.
17 changes: 17 additions & 0 deletions __tests__/castAttribute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,21 @@ describe('castAttribute', () => {
it('should handle invalid JSON when casting', () => {
expect(Model.castAttribute('json', 'not a json string')).toEqual('not a json string');
});

it('should cast date strings to Date objects', () => {
const isoDateString = '2020-01-01T00:00:00.000Z';
const dateObject = Model.castAttribute('date', isoDateString);
expect(dateObject).toBeInstanceOf(Date);
expect(dateObject.toISOString()).toBe(isoDateString);
});

it('should handle invalid date strings when casting', () => {
const invalidDateString = 'not a valid date';
const result = Model.castAttribute('date', invalidDateString);
// Depending on how you want to handle invalid dates,
// you can expect either a null, an invalid Date object, or the original string
// For example, expecting an invalid Date object:
expect(result).toBeInstanceOf(Date);
expect(isNaN(result.getTime())).toBe(true); // Invalid Date object check
});
});
2 changes: 1 addition & 1 deletion dist/Model.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as SQLite from 'expo-sqlite';
type Casts = {
[key: string]: 'number' | 'boolean' | 'string' | 'json';
[key: string]: 'number' | 'boolean' | 'string' | 'date' | 'json';
};
type ModelAttributes = Record<string, any>;
type SQLResult = {
Expand Down
19 changes: 9 additions & 10 deletions dist/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ class Model {
return Boolean(value);
case 'string':
return String(value);
case 'date':
return new Date(value);
case 'json':
try {
return JSON.parse(value);
Expand All @@ -220,26 +222,20 @@ class Model {
const castType = this.casts[key];
switch (castType) {
case 'number':
// Ensure that numbers are finite before storing, otherwise store as null
return isFinite(value) ? Number(value) : null;
case 'boolean':
// Convert boolean to a format that SQLite understands (1 for true, 0 for false)
return value ? 1 : 0;
case 'string':
// Ensure that the value is a string
return String(value);
case 'date':
return value instanceof Date ? value.toISOString() : value;
case 'json':
// Stringify JSON objects
try {
return JSON.stringify(value);
} catch (e) {
// In case of an error (e.g., circular reference), store a null or a placeholder string
// console.error('Error stringifying JSON:', e);
return null; // Or a placeholder string like '{}' or '[]'
return null;
}

default:
// For any type not explicitly handled, return the value as is
return value;
}
}
Expand Down Expand Up @@ -530,7 +526,10 @@ class Model {
exports.Model = Model;
Model.db = SQLite.openDatabase('app.db');
Model.tableName = '';
Model.casts = {};
Model.casts = {
createdAt: 'date',
updatedAt: 'date'
};
Model.withTimestamps = true;
Model.createdAtColumn = 'createdAt';
Model.updatedAtColumn = 'updatedAt';
2 changes: 1 addition & 1 deletion dist/Model.js.map

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions src/Model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as SQLite from 'expo-sqlite'

type Casts = {[key: string]: 'number' | 'boolean' | 'string' | 'json'}
type Casts = {[key: string]: 'number' | 'boolean' | 'string' | 'date' | 'json'}

type Clauses = {
select: string
Expand Down Expand Up @@ -33,7 +33,10 @@ export class Model {

static tableName = ''

static casts: Casts = {}
static casts: Casts = {
createdAt: 'date',
updatedAt: 'date',
}

static withTimestamps: boolean = true;
static createdAtColumn: string = 'createdAt';
Expand Down Expand Up @@ -205,6 +208,8 @@ export class Model {
return Boolean(value);
case 'string':
return String(value);
case 'date':
return new Date(value);
case 'json':
try {
return JSON.parse(value);
Expand All @@ -222,25 +227,20 @@ export class Model {

switch (castType) {
case 'number':
// Ensure that numbers are finite before storing, otherwise store as null
return isFinite(value) ? Number(value) : null;
case 'boolean':
// Convert boolean to a format that SQLite understands (1 for true, 0 for false)
return value ? 1 : 0;
case 'string':
// Ensure that the value is a string
return String(value);
case 'date':
return value instanceof Date ? value.toISOString() : value;
case 'json':
// Stringify JSON objects
try {
return JSON.stringify(value);
} catch (e) {
// In case of an error (e.g., circular reference), store a null or a placeholder string
// console.error('Error stringifying JSON:', e);
return null; // Or a placeholder string like '{}' or '[]'
return null;
}
default:
// For any type not explicitly handled, return the value as is
return value;
}
}
Expand Down

0 comments on commit 788ef68

Please sign in to comment.