google/lovefield

Date fields breaks when the date is represented as a string

pedrettin opened this issue · 4 comments

I am getting the Uncaught TypeError: value.getTime is not a function error when trying to modify a table because the DATE_TIME values in that table are strings instead of dates.

Since I store objects coming from a server directly into lovefield, all dates are represented as strings. This seems to me like a common scenario for people using lovefield. Wouldn't it be more useful if lovefield casted strings passed in as DATE_TIME fields to Date ? Is there a reason why this does not happen?

P.S. I have seen this issue report ( #219 )

Lovefield (per spec), expects a Date object in those columns. Doing runtime type checking to determine whether a DATE_TIME field is actually a Date or a String is not desired for performance reasons. This is a design decision across Lovefield's INSERT/UPDATE APIs to not do any runtime type checking.

User is expected to pre-process the data coming from the server as needed before adding to the database.

Ok, I understand your concern. Would defining type checking in the schema object itself be bad for performance as well ?

I am thinking of something like this

const anObject = {
	
	"value":"a value", 
	
	get a () {
		return this.value
	}, 
	
	set a (val) {
		if (typeof(val) == "string") {
			this.value = val
		} else {
			throw "Invalid type!"
		}
	}
	
}

I dont want to be insistent and you guys have probably already thought of this, but data type consistency is such a good value that a mysql db provides, that it would be nice for lovefield to have it.

In order to insert any row in a Lovefield table, you need to call createRow(myPlainObjectHere). So I don't see much value of embedding that logic in Lovefield when you can already perform pre-processing of raw server data yourself. Example:

const rawObjectsFromServer = .....; // get those somehow
const t = schema.table('MyTable');
const rows = rawObjectsFromServer.map(o => {
  o.dateField = typeof(o.dateField) == "string" ? new Date(o.dateField) : o.dateField;
  return t.createRow(o);
});
db.insert().into(t).values(rows).exec();

Just to give another example. The code will also break if you insert string values in an lf.Type.NUMBER field. Once one starts relaxing the API constraints to do implicit conversions, then why make it only for DATE_TIME, and not make it for everything? Current logic keeps it simple by requiring to provide the correct types always.

Runtime type-checking and throwing an error, might not be as taxing for performance, but in general type checking is better suited for compile-time type-checkers, which can be achieved if you use the SPAC schema, instead of the dynamic schema. Having said that, dynamic schema is more convenient to use than SPAC.

Closing, since there are no action items here. Feel free to continue the discussion in the forum instead.