on master help sign in
added incomplete documentation and more comments
commitb66020b26cc21e36862855c9c442245764bab023 authormelissam <mfm6@st-andrews.ac.uk> dateThu 9 Aug 2012, 16:33 (14 years ago) parent55ba776
4 files changed+118−6
contribs/lib/SQLite3/._sqlexpr.idr contribs/lib/SQLite3/._sqlite3.idr contribs/lib/SQLite3/sqlexpr.idr+17−6 contribs/lib/SQLite3/sqlite3.tex+101
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
2121 |VCol String
2222 |VNULL
2323
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.
2428
2529data Cond = Equals Value Value
2630 |MkGT Value Value
@@ -29,7 +33,7 @@ data Cond = Equals Value Value
2933 |MkLTE Value Value
3034 |MkNULL Value
3135
32−
36+
3337data Clause = MkCond Cond
3438 | AND Clause Clause
3539 | OR Clause Clause
@@ -80,7 +84,8 @@ unwords = pack . unwords' . map unpack
8084
8185-----------------------------------------------------------
8286-- | 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.
8489-----------------------------------------------------------
8590
8691valString : 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
9095valString xs (VCol n) = (n, xs)
9196
9297-----------------------------------------------------------
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.
94100-----------------------------------------------------------
95101
96102listVal : List (Maybe(Int, Value)) -> List Value -> (String, List (Maybe(Int, Value)))
@@ -125,6 +131,7 @@ putBrackets str = "(" ++ str ++ ")"
125131
126132-----------------------------------------------------------
127133-- | Used to detect a complex type in a nested SQLite query
134+-- This function is used for bracketing the nested queries.
128135-----------------------------------------------------------
129136complexType : SQL -> Bool
130137complexType (TBL tbl) = False
@@ -144,7 +151,7 @@ listValType xs ((val, types, constr) :: vs) = let (str , newxs) = valString xs v
144151
145152
146153-----------------------------------------------------------
147−-- | Evaluates a condition after WHERE clause
154+-- | Evaluates a conditional WHERE clause
148155-----------------------------------------------------------
149156
150157evalCond : 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
172179 (restring ++ " IS NULL " , newxs)
173180
174181-----------------------------------------------------------
175−-- | Evaluates queries
182+-- | Evaluates queries by calling the other functions
183+-- on each part of the query
176184-----------------------------------------------------------
177185evalSQL : List (Maybe(Int, Value)) -> SQL -> ( String, List (Maybe(Int, Value)))
178186-----------------------------------------------------------
179187-- | Evaluates clauses
188+-- Supports WHERE Clause
189+-- WHERE Clause And Another-Clause
190+-- WHERE Clause Or Another-Clause
180191-----------------------------------------------------------
181192clauseString : List (Maybe(Int, Value)) -> Clause -> (String, List (Maybe(Int, Value)))
182193
@@ -206,7 +217,7 @@ condClauseStr xs (WHERE setcl1 setcl2) = let (condstr, newxs) = condClauseStr xs
206217 ( condstr ++ " WHERE " ++ condstr', newxs')
207218
208219-- 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 "))))
210221-- NTBF
211222--clauseString xs (MkSQL sql) = (evalSQL xs sql)
212223
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}