sql

lyall 2024-06-15T13:17:37.869349Z

I've got the exact opposite question as TJ above—how do I use next.jdbc to automatically convert between sqlite date strings and real date types when inserting and fetching from the database? I have to assume this is already a solved issue but I haven't been able to find what I'm looking for after banging my head against the documentation and searching online for more time than I'd like to admit

seancorfield 2024-06-16T17:42:55.041109Z

TZ stuff is a pain in every DB. The only advice I can give is use UTC for everything, including the O/S on all your servers...

lyall 2024-06-17T01:03:30.828249Z

yeah I agree UTC for everything is the way to go—just a bit harder to do when doing dev on my personal machine, which is not set to UTC

seancorfield 2024-06-17T01:27:28.250709Z

I start my JVM locally with the UTC timezone. And I run services via Docker locally all set to UTC.

lyall 2024-06-17T01:30:10.229319Z

Ah right I totally forgot you can set the JVM timezone! And I should really get around to setting up docker for this... I'm still early in development so haven't really worried about getting it deployed yet

lyall 2024-06-17T01:32:13.064269Z

though fwiw I did manage to get around the TZ issue I was having by storing the dates in sqlite as unix epoch millis, but I would definitely prefer a more human readable version

lyall 2024-06-15T13:21:15.406009Z

I suppose next.jdbc doesn't have a way to distinguish a date-containing string field from any regular string field, but I still feel like I must be able to somehow easily have the conversion done in a layer below the app logic 🤔

p-himik 2024-06-15T13:45:14.527439Z

Check out the docstring of next.jdbc.result-set/builder-adapter. By default, next.jdbc relies on the implementation of ResultSet.getObject to provide the right types. Since SQLite doesn't have dates, only strings, getObject there returns strings for dates: https://github.com/xerial/sqlite-jdbc/blob/ec0a52436f740357c6315accaa507c33c2e1ffe8/src/main/java/org/sqlite/jdbc3/JDBC3ResultSet.java#L524-L525 But you can ask next.jdbc to call getDate on the right columns instead. Note that there's a default date format that must be used for getDate to work. But you can also alter that format.

lyall 2024-06-15T14:08:22.578989Z

thank you! so I've been looking in the right place, but just didn't quite have it figured out. I got it working with the following:

(def timestamp-columns [:expires-at :created-at])

(defn- timestamp-column-reader [builder rs i]
  (let [col-name (nth (:cols builder) (dec i))
        value (if (some #(= col-name %) timestamp-columns)
                (.getDate rs i)
                (.getObject rs i))]
    (rs/read-column-by-index value (:rsmeta builder) i)))

(def builder-fn (rs/builder-adapter
                 rs/as-unqualified-kebab-maps
                 timestamp-column-reader))

lyall 2024-06-15T14:10:12.904939Z

however I'm not sure if this is really any nicer than just doing the conversion after fetching from the db... pro is I don't have to worry about the date types myself, the driver does that. Con is the code is a bit more obtuse imo

lyall 2024-06-15T14:14:02.088049Z

given the popularity of sqlite, I'm a bit shocked this isn't built in somewhere at a lower level. But maybe I'm just going about this all wrong or something

seancorfield 2024-06-15T16:17:54.091999Z

Does SQLite provide column type information? There are some tests in next.jdbc around BIT/BOOL handling that auto convert by type (not name) for SQLite that might help you here.

lyall 2024-06-15T23:38:31.432799Z

I’m brand new to using SQLite, so frankly not sure but I’ll have to look into it. I do have the relevant columns declared as TIMESTAMP, but I’m not sure if SQLite stores that fact somewhere or just treats it at another way of spelling TEXT

lyall 2024-06-16T01:42:32.803809Z

aha that works perfectly! the column type name is in fact preserved as TIMESTAMP 😌

lyall 2024-06-16T02:43:42.988769Z

ah well now I'm actually running into time zone issues... the xerial/sqlite-jdbc driver seems to be assuming some wrong stuff about time zones. Though it seems it's configurable through it's configuration—are the xerial/sqlite-jdbc configuration options accessible through next.jdbc or do I have to figure out some other way to set them? I haven't been able to find anything about that type of config in the docs so far