0 | module Oracle.Types.Row
 1 |
 2 | import Oracle.Types.BindParameter
 3 | import Oracle.Types.Error
 4 | import Oracle.Types.Value
 5 |
 6 | ||| Decode a single Oracle value into an Idris type.
 7 | |||
 8 | ||| This interface is the typed counterpart to `ToOracleValue`.
 9 | |||
10 | ||| It is responsible only for converting a single `OracleValue` into the requested Idris type.
11 | |||
12 | ||| Typical instances include:
13 | ||| - `String`
14 | ||| - `Double`
15 | ||| - `Bool`
16 | ||| - `ByteString`
17 | ||| - `OracleTimestamp`
18 | ||| - `OracleTimestampTZ`
19 | ||| - `OracleIntervalYM`
20 | ||| - `OracleIntervalDS`
21 | |||
22 | ||| This interface intentionally does not perform any row-level decoding, as that responsibility belongs to `FromRow`.
23 | |||
24 | ||| Example:
25 | |||
26 | ||| ```idris
27 | ||| implementation FromOracle Double where
28 | |||   fromOracle (OracleNumber n) = Right n
29 | |||   fromOracle value =
30 | |||     Left $
31 | |||       MkOracleError
32 | |||         (-1)
33 | |||         ("Expected NUMBER but got " ++ show value)
34 | |||         "FromOracle Double"
35 | |||         False
36 | ||| ```
37 | |||
38 | public export
39 | interface FromOracle a where
40 |   fromOracle : OracleValue -> Either OracleError a
41 |
42 | ||| Convert an Idris record into a collection of named bind parameters.
43 | |||
44 | ||| This interface is intended for values that will be supplied to SQL statements as bind variables.
45 | |||
46 | ||| Each returned `BindParameter` associates a named placeholder (such as `:name`) with the Oracle value that should be sent to the database.
47 | |||
48 | ||| Unlike `FromOracle`, this interface operates on complete records rather than individual values.
49 | |||
50 | ||| Example:
51 | |||
52 | ||| ```idris
53 | ||| implementation ToRow Person where
54 | |||   toRow person =
55 | |||     [ MkBindParameter ":name" (OracleString person.name)
56 | |||     , MkBindParameter ":age"  (OracleNumber person.age)
57 | |||     ]
58 | ||| ```
59 | |||
60 | ||| The ordering of bind parameters is not significant when binding by name, but using the SQL declaration order is recommended for readability.
61 | |||
62 | public export
63 | interface ToRow a where
64 |   toRow : a -> List BindParameter
65 |
66 | ||| Decode a complete database row into an Idris value.
67 | |||
68 | ||| A `FromRow` instance describes how an ordered list of `OracleValue`s returned by Oracle should be assembled into an application type.
69 | |||
70 | ||| Most implementations simply pattern-match on the expected row shape and delegate the decoding of each individual column to `FromOracle`.
71 | |||
72 | ||| Example:
73 | |||
74 | ||| ```idris
75 | ||| implementation FromRow Person where
76 | |||   fromRow [name, age] = do
77 | |||     name' <- fromOracle name
78 | |||     age'  <- fromOracle age
79 | |||     pure (MkPerson name' age')
80 | |||
81 | |||   fromRow row =
82 | |||     Left $
83 | |||       MkOracleError
84 | |||         (-1)
85 | |||         ("Unexpected PERSON row: " ++ show row)
86 | |||         "Person.fromRow"
87 | |||         False
88 | ||| ```
89 | |||
90 | ||| This interface is used by the typed query APIs (`query_`, `queryOne`, and `queryExactlyOne`) to transform raw query results into strongly typed Idris values.
91 | |||
92 | public export
93 | interface FromRow a where
94 |   fromRow : List OracleValue -> Either OracleError a
95 |