5 | import Data.ByteString
6 | import Data.List.Quantifiers
9 | import Sqlite3.Marshall
10 | import Sqlite3.Parameter
11 | import Sqlite3.Types
16 | idris_sqlite : String -> String
17 | idris_sqlite fn = "C:" ++ fn ++ ",libsqlite3-idris"
25 | data DBPtr : Type where
36 | data StmtPtr : Type where
49 | %foreign (idris_sqlite "newptr")
50 | prim__newptr : PrimIO AnyPtr
52 | %foreign (idris_sqlite "ptr_free")
53 | prim__ptr_free : AnyPtr -> PrimIO ()
55 | %foreign (idris_sqlite "null")
58 | %foreign (idris_sqlite "deref")
59 | prim__deref : Ptr AnyPtr -> PrimIO AnyPtr
61 | %foreign (idris_sqlite "mkString")
62 | prim__mkString : String -> PrimIO (Ptr String)
64 | %foreign (idris_sqlite "getString")
65 | prim__getString : Ptr String -> PrimIO String
67 | %foreign (idris_sqlite "copy_buffer")
68 | prim__copy_buffer : Bits32 -> Buffer -> AnyPtr -> PrimIO ()
70 | %foreign (idris_sqlite "sqlver")
71 | prim__sqlite_ver : PrimIO ()
73 | %foreign (idris_sqlite "sqlite3_free")
74 | prim__sqlite3_free : AnyPtr -> PrimIO AnyPtr
76 | %foreign (idris_sqlite "sqlite3_malloc")
77 | prim__sqlite3_malloc : Int -> PrimIO AnyPtr
79 | %foreign (idris_sqlite "sqlite3_open")
80 | prim__sqlite_open : String -> Ptr (Ptr DBPtr) -> PrimIO Int
83 | %foreign (idris_sqlite "sqlite3_open_v2")
84 | prim__sqlite_open_v2 : String -> Ptr (Ptr DBPtr) -> Int -> String -> PrimIO Int
86 | %foreign (idris_sqlite "sqlite3_close")
87 | prim__sqlite_close : Ptr DBPtr -> PrimIO Int
89 | %foreign (idris_sqlite "sqlite3_prepare_v2")
90 | prim__sqlite_prepare : Ptr DBPtr -> String -> Int -> Ptr (Ptr StmtPtr) -> Ptr (Ptr String) -> PrimIO Int
92 | %foreign (idris_sqlite "sqlite3_step")
93 | prim__sqlite_step : Ptr StmtPtr -> PrimIO Int
95 | %foreign (idris_sqlite "sqlite3_exec")
96 | prim__sqlite_exec : Ptr DBPtr -> String -> AnyPtr -> AnyPtr -> Ptr String -> PrimIO Int
98 | %foreign (idris_sqlite "sqlite3_finalize")
99 | prim__sqlite3_finalize : Ptr StmtPtr -> PrimIO Int
101 | %foreign (idris_sqlite "sqlite3_extended_errcode")
102 | prim__sqlite3_extended_errcode : Ptr DBPtr -> PrimIO Int
104 | %foreign (idris_sqlite "sqlite3_errmsg")
105 | prim__sqlite3_errmsg : Ptr DBPtr -> PrimIO String
107 | %foreign (idris_sqlite "sqlite3_errstr")
108 | prim__sqlite3_errstr : Int -> PrimIO String
110 | %foreign (idris_sqlite "sqlite3_column_text")
111 | prim__sqlite3_column_text : Ptr StmtPtr -> (iCol : Bits32) -> PrimIO (Ptr String)
113 | %foreign (idris_sqlite "sqlite3_column_blob")
114 | prim__sqlite3_column_blob : Ptr StmtPtr -> (iCol : Bits32) -> PrimIO AnyPtr
116 | %foreign (idris_sqlite "sqlite3_column_double")
117 | prim__sqlite3_column_double : Ptr StmtPtr -> (iCol : Bits32) -> PrimIO Double
119 | %foreign (idris_sqlite "sqlite3_column_type")
120 | prim__sqlite3_column_type : Ptr StmtPtr -> (iCol : Bits32) -> PrimIO Bits8
122 | %foreign (idris_sqlite "sqlite3_column_int")
123 | prim__sqlite3_column_int32 : Ptr StmtPtr -> (iCol : Bits32) -> PrimIO Int32
125 | %foreign (idris_sqlite "sqlite3_column_int64")
126 | prim__sqlite3_column_int64 : Ptr StmtPtr -> (iCol : Bits32) -> PrimIO Int64
128 | %foreign (idris_sqlite "sqlite3_column_bytes")
129 | prim__sqlite3_column_bytes : Ptr StmtPtr -> (iCol : Bits32) -> PrimIO Bits32
131 | %foreign (idris_sqlite "sqlite3_column_count")
132 | prim__sqlite3_column_count : Ptr StmtPtr -> PrimIO Bits32
134 | %foreign (idris_sqlite "bind_text")
135 | prim__sqlite3_bind_text : Ptr StmtPtr -> (ix : Bits32) -> String -> PrimIO Int
137 | %foreign (idris_sqlite "bind_buffer")
138 | prim__sqlite3_bind_blob : Ptr StmtPtr -> (ix : Bits32) -> Buffer -> (size : Bits32) -> PrimIO Int
140 | %foreign (idris_sqlite "sqlite3_bind_double")
141 | prim__sqlite3_bind_double : Ptr StmtPtr -> (ix : Bits32) -> Double -> PrimIO Int
143 | %foreign (idris_sqlite "sqlite3_bind_int")
144 | prim__sqlite3_bind_int32 : Ptr StmtPtr -> (ix : Bits32) -> Int32 -> PrimIO Int
146 | %foreign (idris_sqlite "sqlite3_bind_int64")
147 | prim__sqlite3_bind_int64 : Ptr StmtPtr -> (ix : Bits32) -> Int64 -> PrimIO Int
149 | %foreign (idris_sqlite "sqlite3_bind_parameter_index")
150 | prim__sqlite3_bind_parameter_index : Ptr StmtPtr -> String -> PrimIO Bits32
152 | %foreign (idris_sqlite "sqlite3_bind_null")
153 | prim__sqlite3_bind_null : Ptr StmtPtr -> (ix : Bits32) -> PrimIO Int
155 | %foreign (idris_sqlite "sqlite3_last_insert_rowid")
156 | prim__sqlite3_last_insert_rowid : Ptr DBPtr -> PrimIO Int64
164 | ptrFree : Ptr t -> IO ()
165 | ptrFree ptr = primIO $
prim__ptr_free $
prim__forgetPtr ptr
169 | newAnyPtr : IO AnyPtr
170 | newAnyPtr = primIO prim__newptr
174 | newPtr : IO (Ptr t)
175 | newPtr = prim__castPtr <$> newAnyPtr
179 | dereference : Ptr (Ptr t) -> IO (Ptr t)
181 | prim__castPtr <$> (primIO $
prim__deref (believe_me ptr))
184 | strToPtr : String -> IO (Ptr String)
185 | strToPtr = primIO . prim__mkString
190 | nullPtr = prim__castPtr $
prim__null
194 | withPtr : Ptr a -> (Ptr a -> IO b) -> IO b
195 | withPtr ptr act = act ptr <* ptrFree ptr
199 | withPtrAlloc : (Ptr a -> IO b) -> IO b
200 | withPtrAlloc act = newPtr >>= (`withPtr` act)
204 | ptrToStr : Ptr String -> IO String
205 | ptrToStr = primIO . prim__getString
213 | sqlite3ErrMsg : (d : DB) => IO String
214 | sqlite3ErrMsg = primIO $
prim__sqlite3_errmsg d.db
217 | sqlFailRes : DB => SqlResult -> IO (Either SqlError a)
219 | msg <- sqlite3ErrMsg
220 | pure (Left $
ResultError r msg)
223 | sqlFail : DB => Int -> IO (Either SqlError a)
224 | sqlFail = sqlFailRes . fromInt
232 | sqlite3LastInsertRowID : DB => IO Int64
233 | sqlite3LastInsertRowID @{D p} = primIO $
prim__sqlite3_last_insert_rowid p
237 | sqlite3ColumnCount : (s : Stmt) => IO Bits32
238 | sqlite3ColumnCount = primIO $
prim__sqlite3_column_count s.stmt
246 | sqlite3ColumnText : (s : Stmt) => (iCol : Bits32) -> IO String
247 | sqlite3ColumnText iCol = do
248 | ptr <- primIO $
prim__sqlite3_column_text s.stmt iCol
257 | sqlite3ColumnBlob : (s : Stmt) => (iCol : Bits32) -> IO ByteString
258 | sqlite3ColumnBlob iCol = do
259 | ptr <- primIO $
prim__sqlite3_column_blob s.stmt iCol
260 | n <- primIO $
prim__sqlite3_column_bytes s.stmt iCol
261 | Just buf <- newBuffer (cast n) | Nothing => pure empty
262 | primIO $
prim__copy_buffer n buf ptr
263 | pure $
unsafeByteString (cast n) buf
267 | sqlite3ColumnDouble : (s : Stmt) => (iCol : Bits32) -> IO Double
268 | sqlite3ColumnDouble = primIO . prim__sqlite3_column_double s.stmt
272 | sqlite3ColumnInt32 : (s : Stmt) => (iCol : Bits32) -> IO Int32
273 | sqlite3ColumnInt32 = primIO . prim__sqlite3_column_int32 s.stmt
277 | sqlite3ColumnInt64 : (s : Stmt) => (iCol : Bits32) -> IO Int64
278 | sqlite3ColumnInt64 = primIO . prim__sqlite3_column_int64 s.stmt
292 | sqliteOpen : (path : String) -> IO (Either SqlError DB)
293 | sqliteOpen fn = withPtrAlloc $
\db_ptr => do
294 | 0 <- primIO (prim__sqlite_open fn db_ptr)
295 | | r => pure (Left $
ResultError (fromInt r) "unable to open connect to \{fn}")
296 | Right . D <$> dereference db_ptr
301 | sqliteClose : DB -> IO SqlResult
302 | sqliteClose d = fromInt <$> primIO (prim__sqlite_close d.db)
306 | sqliteClose' : DB -> IO ()
307 | sqliteClose' = ignore . sqliteClose
318 | sqliteFinalize : Stmt -> IO SqlResult
319 | sqliteFinalize s = fromInt <$> primIO (prim__sqlite3_finalize s.stmt)
323 | sqliteFinalize' : Stmt -> IO ()
324 | sqliteFinalize' = ignore . sqliteFinalize
328 | sqlitePrepare : (d : DB) => String -> IO (Either SqlError Stmt)
329 | sqlitePrepare s = withPtrAlloc $
\stmt_ptr => do
330 | 0 <- primIO (prim__sqlite_prepare d.db s (-
1) stmt_ptr nullPtr)
332 | Right . S <$> dereference stmt_ptr
334 | bindParam : DB => Stmt -> Parameter -> IO Int
335 | bindParam s (P n t v) = do
336 | ix <- fromPrim $
prim__sqlite3_bind_parameter_index s.stmt n
338 | INTEGER => fromPrim $
prim__sqlite3_bind_int64 s.stmt ix v
339 | REAL => fromPrim $
prim__sqlite3_bind_double s.stmt ix v
340 | TEXT => fromPrim $
prim__sqlite3_bind_text s.stmt ix v
343 | fromPrim $
prim__sqlite3_bind_blob s.stmt ix buf (cast v.size)
345 | bindParams : DB => Stmt -> List Parameter -> IO Int
346 | bindParams stmt [] = pure 0
347 | bindParams stmt (x :: xs) = do
348 | 0 <- bindParam stmt x | x => pure x
353 | sqliteBind : (d : DB) => (s : Stmt) => List Parameter -> IO (Either SqlError ())
355 | 0 <- bindParams s xs | r => sqlFail r
369 | sqliteStep : Stmt -> IO SqlResult
370 | sqliteStep s = fromInt <$> primIO (prim__sqlite_step s.stmt)
379 | -> (t : SqliteType)
381 | -> IO (Either SqlError $
Maybe (IdrisType t))
382 | tryLoad 1 INTEGER ix = Right . Just <$> sqlite3ColumnInt64 ix
383 | tryLoad 2 REAL ix = Right . Just <$> sqlite3ColumnDouble ix
384 | tryLoad 3 TEXT ix = Right . Just <$> sqlite3ColumnText ix
385 | tryLoad 4 BLOB ix = Right . Just <$> sqlite3ColumnBlob ix
386 | tryLoad 5 _ ix = pure (Right Nothing)
387 | tryLoad 1 t ix = pure $
Left (TypeMismatch t INTEGER)
388 | tryLoad 2 t ix = pure $
Left (TypeMismatch t REAL)
389 | tryLoad 3 t ix = pure $
Left (TypeMismatch t TEXT)
390 | tryLoad _ t ix = pure $
Left (TypeMismatch t BLOB)
396 | -> IO (Either SqlError $
Maybe (IdrisType t))
398 | tpe <- fromPrim $
prim__sqlite3_column_type s.stmt ix
407 | {ts : List SqliteType}
409 | -> IO (Either SqlError $
All (Maybe . IdrisType) ts)
411 | ncols <- sqlite3ColumnCount
412 | go (cast ncols) 0 ts
418 | -> (ss : List SqliteType)
419 | -> IO (Either SqlError $
All (Maybe . IdrisType) ss)
420 | go _ _ [] = pure (Right [])
421 | go 0 _ (t::ss) = pure (Left NoMoreData)
422 | go (S k) col (t::ss) = do
423 | Right c <- loadCell col | Left err => pure (Left err)
424 | Right cs <- go k (col +1) ss | Left err => pure (Left err)
425 | pure (Right $
c :: cs)
432 | -> {auto ps : FromRow a}
434 | -> IO (Either SqlError $
List a)
437 | go : SnocList a -> Nat -> IO (Either SqlError $
List a)
438 | go sr 0 = pure (Right $
sr <>> [])
440 | SQLITE_ROW <- sqliteStep s
441 | | SQLITE_DONE => pure (Right $
sr <>> [])
442 | | res => sqlFailRes res
443 | Right r <- loadRow | Left err => pure (Left err)
444 | case fromRow {a} r of
445 | Right v => go (sr :< v) k
446 | Left err => pure (Left err)