on master help sign in
added incomplete documentation and more comments
b66020bmelissam
contribs/lib/SQLite3/._sqlexpr.idr

Binary file not shown.

contribs/lib/SQLite3/._sqlite3.idr

Binary file not shown.

contribs/lib/SQLite3/sqlexpr.idr+17−6
@@ -21,6 +21,10 @@ data Value = VInt Int
21 |VCol String
21 |VCol String
22 |VNULL
22 |VNULL
23
23
24+--Perhaps could extend this by adding
25+-- a dot operator to allow mapping
26+-- between table and column and
27+-- comparing different table columns.
24
28
25data Cond = Equals Value Value
29data Cond = Equals Value Value
26 |MkGT Value Value
30 |MkGT Value Value
@@ -29,7 +33,7 @@ data Cond = Equals Value Value
29 |MkLTE Value Value
33 |MkLTE Value Value
30 |MkNULL Value
34 |MkNULL Value
31
35
32−
36+
33data Clause = MkCond Cond
37data Clause = MkCond Cond
34 | AND Clause Clause
38 | AND Clause Clause
35 | OR Clause Clause
39 | OR Clause Clause
@@ -80,7 +84,8 @@ unwords = pack . unwords' . map unpack
80
84
81-----------------------------------------------------------
85-----------------------------------------------------------
82-- | This function replaces values with question mark
86-- | This function replaces values with question mark
83−-- following by an index number.
87+-- following by an index number. It then puts the value
88+-- replaced, in the list.
84-----------------------------------------------------------
89-----------------------------------------------------------
85
90
86valString : List (Maybe(Int, Value)) -> Value -> (String, List (Maybe(Int, Value)))
91valString : List (Maybe(Int, Value)) -> Value -> (String, List (Maybe(Int, Value)))
@@ -90,7 +95,8 @@ valString xs (VFloat x) = ("?" ++ show (cast(length xs)+1), xs ++ [Just (cast((l
90valString xs (VCol n) = (n, xs)
95valString xs (VCol n) = (n, xs)
91
96
92-----------------------------------------------------------
97-----------------------------------------------------------
93−-- | This function calls valString on a list of Values.
98+-- | This function calls valString on a list of Values
99+-- and separates the values by commas.
94-----------------------------------------------------------
100-----------------------------------------------------------
95
101
96listVal : List (Maybe(Int, Value)) -> List Value -> (String, List (Maybe(Int, Value)))
102listVal : List (Maybe(Int, Value)) -> List Value -> (String, List (Maybe(Int, Value)))
@@ -125,6 +131,7 @@ putBrackets str = "(" ++ str ++ ")"
125
131
126-----------------------------------------------------------
132-----------------------------------------------------------
127-- | Used to detect a complex type in a nested SQLite query
133-- | Used to detect a complex type in a nested SQLite query
134+-- This function is used for bracketing the nested queries.
128-----------------------------------------------------------
135-----------------------------------------------------------
129complexType : SQL -> Bool
136complexType : SQL -> Bool
130complexType (TBL tbl) = False
137complexType (TBL tbl) = False
@@ -144,7 +151,7 @@ listValType xs ((val, types, constr) :: vs) = let (str , newxs) = valString xs v
144
151
145
152
146-----------------------------------------------------------
153-----------------------------------------------------------
147−-- | Evaluates a condition after WHERE clause
154+-- | Evaluates a conditional WHERE clause
148-----------------------------------------------------------
155-----------------------------------------------------------
149
156
150evalCond : List (Maybe(Int, Value)) -> Cond -> (String, List (Maybe(Int, Value)))
157evalCond : List (Maybe(Int, Value)) -> Cond -> (String, List (Maybe(Int, Value)))
@@ -172,11 +179,15 @@ evalCond xs (MkNULL val) = let (restring , newxs ) = valString xs val in
172 (restring ++ " IS NULL " , newxs)
179 (restring ++ " IS NULL " , newxs)
173
180
174-----------------------------------------------------------
181-----------------------------------------------------------
175−-- | Evaluates queries
182+-- | Evaluates queries by calling the other functions
183+-- on each part of the query
176-----------------------------------------------------------
184-----------------------------------------------------------
177evalSQL : List (Maybe(Int, Value)) -> SQL -> ( String, List (Maybe(Int, Value)))
185evalSQL : List (Maybe(Int, Value)) -> SQL -> ( String, List (Maybe(Int, Value)))
178-----------------------------------------------------------
186-----------------------------------------------------------
179-- | Evaluates clauses
187-- | Evaluates clauses
188+-- Supports WHERE Clause
189+-- WHERE Clause And Another-Clause
190+-- WHERE Clause Or Another-Clause
180-----------------------------------------------------------
191-----------------------------------------------------------
181clauseString : List (Maybe(Int, Value)) -> Clause -> (String, List (Maybe(Int, Value)))
192clauseString : List (Maybe(Int, Value)) -> Clause -> (String, List (Maybe(Int, Value)))
182
193
@@ -206,7 +217,7 @@ condClauseStr xs (WHERE setcl1 setcl2) = let (condstr, newxs) = condClauseStr xs
206 ( condstr ++ " WHERE " ++ condstr', newxs')
217 ( condstr ++ " WHERE " ++ condstr', newxs')
207
218
208-- SELECT data from tbl1 where num > (SELECT num from tbl1 where num = 24)
219-- SELECT data from tbl1 where num > (SELECT num from tbl1 where num = 24)
209−-- evalSQL [] ((SELECT ALL) (TBL "tbl") (MkSQL ((SELECT ALL) (TBL "tbl") (MkCond (VCol ") ) ) )
220+-- evalSQL [] ((SELECT ALL)(TBL "tbl")(MkSQL ((SELECT ALL) (TBL "tbl")(MkCond (VCol "))))
210-- NTBF
221-- NTBF
211--clauseString xs (MkSQL sql) = (evalSQL xs sql)
222--clauseString xs (MkSQL sql) = (evalSQL xs sql)
212
223
contribs/lib/SQLite3/sqlite3.texnew file+101
@@ -0,0 +1,101 @@
1+ \documentclass[11pt]{article}
2+ \topmargin -1.5cm
3+ \oddsidemargin -0.04cm
4+ \evensidemargin -0.04cm
5+ \textwidth 16.59cm
6+ \textheight 21.94cm
7+ %\pagestyle{empty}
8+ \parskip 7.2pt
9+ \parindent 0pt
10+
11+ \begin{document}
12+ \section{Introduction}
13+\label{Introduction}
14+This document provides overview of how the library for SQLite works. The code base is written on top of the SQLite3 C/C++ Interface. This library supports some features of the low-level library, implemented in a higher level basis.
15+The library allows making use of data types as queries. The aim of this library is to avoid SQL injections which are the most common security issues. To avoid this we have defined a datatype which describes qqueries. The queries are written using these data types and parsed as quoted string while replacing values with indexed question mark to be binded with the statement.
16+\section{Using the library}
17+\label{Using the library}
18+Simple examples have been provided in the testunit.idr file.
19+To open a database, use the open\_db function which takes the filename as a string. This function implements the sqlite3\_open function . This function returns a pointer to the database which can be used by other function to access the database object.
20+Whether or not an error occurs when it is opened, resources should be released by passing it to close\_db when it is no longer required.
21+A query can then be builts using the supported data types . The library supports limited number of queries at the moment. The supported sql commands are :
22+\newline
23+\newline
24+\textbf{SELECT,}
25+\textbf{INSERT,}
26+\textbf{UPDATE,}
27+\textbf{CREATE}
28+
29+\subsection{Creating Queries}
30+\label{Creating Queries}
31+
32+To create a query, use the evalSQL function which takes an empty list and the SQL query. The routine evaluates the expression in a divide and conquer manner (or recursive?)
33+filling up the list with the received values. For instance the following is a valid query:
34+
35+let sql = evalSQL [ ] ((SELECT ALL)(TBL ["tbl1"]) (MkCond (MkNULL (VCol "data"))))
36+\newline
37+\newline{This will be parsed as :}
38+\\“SELECT * FROM tbl1 WHERE data IS NULL “
39+
40+The evaluator returns a string and a list of indexed values. The string part of the query could be parsed to prepare.
41+evalSQL parses the query as a string replacing values with ? and an index starting from one, storing them in the list given to it as an argument.
42+For example:
43+
44+
45+evalSQL [ ] (SELECT (Cols ["data"]) (SELECT (Cols["num","data"]) (TBL ["tbl1"]) (MkCond (Equals (VCol "num")(VInt 2))) ) Empty ) )
46+
47+is passed to prepare as :
48+
49+SELECT * FROM tbl1 WHERE data = ?1 AND num = ?2 OR num = ?3
50+
51+and returns the list as follows:
52+\newline{(Just (1, VStr "data0")) ,(Just (2, VInt 1)) , (Just (3, VInt 2))}
53+
54+The values in the list are binded to the statement using bindMulti function. This function takes the statement pointer returned by prepare and the list returned by evalSQL, and binds the values by calling the appropriate functions.
55+
56+The function exec\_db\_v2 executes the statement. Note that the other version of exec\_db implements the sqlite3\_exec() interface which is a wrapper around sqlite3\_prepare\_v2(), sqlite3\_step(), and sqlite3\_finalize(), without having to use a lot of code, though the use of this function is not recommended in this case.
57+
58+The functions finalize\_db and close\_db must be called to clean up the open resources.
59+To print the result, the function toList\_v1 can be used which takes a DBPointer.
60+
61+\subsection{More Examples}
62+\label{More Examples}
63+Nested expressions are also supported. You could write queries such as :
64+
65+evalSQL [ ] (SELECT (Cols ["data"]) (SELECT (Cols["num","data"]) (TBL ["tbl1"]) (MkCond (Equals (VCol "num")(VInt 2)))) Empty)
66+
67+Parsed as :
68+
69+SELECT data FROM (SELECT num data FROM tbl1 WHERE num = ?1)
70+
71+Note that in this example, the inner query must include the same column as the outer one otherwise this query will not validate.
72+Use tricky examples of things that work and things that dont work
73+
74+\section{Evaluating Queries}
75+\label{Evaluating Queries}
76+\subsection{SQL Data Type}
77+\label{SQL Data Type}
78+The SQL Data Types describe the queries that are supported by the library. Data type Value consists of Int, String and Float. The data type can be extended to further support queries. The evaulator function makes use of smaller function to evaulate parts of the query. For instance given a SELECT qeury, it calls evalSQL to obtain the list of tables, and clauseString to evaluate the rest of the expression which could include a WHERE clause or could be Empty.
79+\subsection{evalSQL Function}
80+\label{evalSQL Function}
81+This is a recursive evaluator which makes a call to itself. An SQL could consist of a SELECT ALL or Columns followed by another SQL which could be a nested query or just the name of the table(s). It then call the appropriate functions to evaluate the query. It returns the well-quoted String expression and a list of indexed values which are passed to the bind function.
82+\section{Pointers passed to Idris functions}
83+\label{Pointers passed to Idris functions}
84+
85+The library uses FFI. In order to make the pointers passed to functions more explicit, we have defined them as data types. For instance open\_db takes a String and returns a DBPointer and prepare\_db
86+takes a DBPointer and returns a StmtPtr(Statemenet Pointer).
87+Error handling is done using the \emph {DB a} data type which is either \emph {IO String} which indicates an error or \emph{ IO a}.
88+To test the functions in main, you need to use runDB which takes a \emph{ DB a} and returns IO a.
89+\begin{center}
90+\centering runDB : DB a $\rightarrow$ IO a
91+\end{center}
92+More examples on how to use the functions can be found in \emph{testunit.idr}
93+
94+\section{Using the C Functions}
95+\label{Using the C Functions}
96+
97+For example calling get\_table after prepare\_db could lead to segmentation fault since get\_table calls sqlite3\_prepare etc
98+Functions such as exec\_db and get\_table are wrapper functions and calling these before finalizing a prepared query could cause segmentation fault.
99+Perhaps these functions could be removed from the library if no longer required in the future.
100+
101+\end{document}