I'm trying to load data from a SQLite database, but I can't know the data format, since it's user provided.
This works if all columns are of the same type:
(entries :: [[Text]]) <- query_ connection "select * from users"
But what can I do if the columns have different types (e.g. INTEGER or REAL)?
CodePudding user response:
TLDR: Use entries :: [[SQLData]]
You seem to be using sqlite-simple. In that package, the type of query_
is
query_ :: FromRow r => Connection -> Query -> IO [r]
query_
uses the FromRow
and (indirectly) FromField
typeclasses. These are helpers that transform incoming sqlite row and column data to the format expected by the user.
However, these transformations might fail when the source and output types are not convertible.
The SQLData
represents the "raw" untransformed sqlite datatypes. Converting a column value to SQLData
is a no-op and never fails. And using [SQLData]
for the rows never fails either, because lists can handle any number of columns (unlike, say, a (SQLData,SQLData)
tuple).
Therefore, when dealing with unknown schemas, we can use [SQLData]
as the row type and then pattern-match on the SQLData
values to discover what are the actual sqlite types.