@@ -0,0 +1,85 @@
1+module Yoga.NodeSQLite.NodeSQLite where
5+import Data.Either (Either(..))
6+import Data.Maybe (Maybe)
7+import Data.Newtype (class Newtype)
8+import Data.Nullable (Nullable)
9+import Data.Nullable as Nullable
10+import Effect (Effect)
11+import Effect.Uncurried (EffectFn1, EffectFn2, runEffectFn1, runEffectFn2)
12+import Foreign (Foreign)
14+-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
15+-- Opaque Foreign Types
16+-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
18+foreign import data Database :: Type
19+foreign import data Statement :: Type
21+-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
22+-- Newtypes for Type Safety
23+-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
25+newtype DatabasePath = DatabasePath String
27+derive instance Newtype DatabasePath _
28+derive newtype instance Show DatabasePath
30+-- | Special in-memory database path
31+inMemory :: DatabasePath
32+inMemory = DatabasePath ":memory:"
34+-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
36+-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
38+foreign import openImpl :: EffectFn1 String Database
39+foreign import closeImpl :: EffectFn1 Database Unit
40+foreign import execImpl :: EffectFn2 String Database Unit
41+foreign import prepareImpl :: EffectFn2 String Database Statement
42+foreign import runImpl :: EffectFn2 (Array Foreign) Statement Unit
43+foreign import getImpl :: EffectFn2 (Array Foreign) Statement (Nullable Foreign)
44+foreign import allImpl :: EffectFn2 (Array Foreign) Statement (Array Foreign)
45+foreign import finalizeImpl :: EffectFn1 Statement Unit
47+-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
48+-- Database Operations
49+-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
51+-- | Open a database connection
52+open :: DatabasePath -> Effect Database
53+open (DatabasePath path) = runEffectFn1 openImpl path
55+-- | Close a database connection
56+close :: Database -> Effect Unit
57+close = runEffectFn1 closeImpl
59+-- | Execute SQL (for DDL/DML without results)
60+exec :: String -> Database -> Effect Unit
61+exec sql db = runEffectFn2 execImpl sql db
63+-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
64+-- Prepared Statements
65+-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
67+-- | Prepare a statement
68+prepare :: String -> Database -> Effect Statement
69+prepare sql db = runEffectFn2 prepareImpl sql db
71+-- | Run a statement (INSERT/UPDATE/DELETE)
72+run :: Array Foreign -> Statement -> Effect Unit
73+run params stmt = runEffectFn2 runImpl params stmt
76+get :: Array Foreign -> Statement -> Effect (Maybe Foreign)
77+get params stmt = runEffectFn2 getImpl params stmt <#> Nullable.toMaybe
80+all :: Array Foreign -> Statement -> Effect (Array Foreign)
81+all params stmt = runEffectFn2 allImpl params stmt
83+-- | Finalize a statement
84+finalize :: Statement -> Effect Unit
85+finalize = runEffectFn1 finalizeImpl