@@ -17,6 +17,8 @@ defmodule Sqlitex.Server do
1717 {:ok, [%{a: 1, b: 1}]}
1818 iex> Sqlitex.Server.query_rows(:example, "SELECT * FROM t ORDER BY a LIMIT 2")
1919 {:ok, %{rows: [[1, 1], [2, 2]], columns: [:a, :b], types: [:INTEGER, :INTEGER]}}
20+ iex> Sqlitex.Server.prepare(:example, "SELECT * FROM t")
21+ {:ok, %{columns: [:a, :b], types: [:INTEGER, :INTEGER]}}
2022 iex> Sqlitex.Server.stop(:example)
2123 :ok
2224 iex> :timer.sleep(10) # wait for the process to exit asynchronously
@@ -39,44 +41,75 @@ defmodule Sqlitex.Server do
3941
4042 use GenServer
4143
44+ alias Sqlitex.Statement
45+ alias Sqlitex.Server.StatementCache , as: Cache
46+
4247 def start_link ( db_path , opts \\ [ ] ) do
43- GenServer . start_link ( __MODULE__ , db_path , opts )
48+ stmt_cache_size = Keyword . get ( opts , :stmt_cache_size , 20 )
49+ GenServer . start_link ( __MODULE__ , { db_path , stmt_cache_size } , opts )
4450 end
4551
4652 ## GenServer callbacks
4753
48- def init ( db_path ) do
54+ def init ( { db_path , stmt_cache_size } )
55+ when is_integer ( stmt_cache_size ) and stmt_cache_size > 0
56+ do
4957 case Sqlitex . open ( db_path ) do
50- { :ok , db } -> { :ok , db }
58+ { :ok , db } -> { :ok , { db , __MODULE__ . StatementCache . new ( db , stmt_cache_size ) } }
5159 { :error , reason } -> { :stop , reason }
5260 end
5361 end
5462
55- def handle_call ( { :exec , sql } , _from , db ) do
63+ def handle_call ( { :exec , sql } , _from , { db , stmt_cache } ) do
5664 result = Sqlitex . exec ( db , sql )
57- { :reply , result , db }
65+ { :reply , result , { db , stmt_cache } }
66+ end
67+
68+ def handle_call ( { :query , sql , opts } , _from , { db , stmt_cache } ) do
69+ with { % Cache { } = new_cache , stmt } <- Cache . prepare ( stmt_cache , sql ) ,
70+ { :ok , stmt } <- Statement . bind_values ( stmt , Keyword . get ( opts , :bind , [ ] ) ) ,
71+ { :ok , rows } <- Statement . fetch_all ( stmt , Keyword . get ( opts , :into , [ ] ) )
72+ do
73+ { :reply , { :ok , rows } , { db , new_cache } }
74+ else
75+ err -> { :reply , err , { db , stmt_cache } }
76+ end
5877 end
5978
60- def handle_call ( { :query , sql , opts } , _from , db ) do
61- rows = Sqlitex . query ( db , sql , opts )
62- { :reply , rows , db }
79+ def handle_call ( { :query_rows , sql , opts } , _from , { db , stmt_cache } ) do
80+ with { % Cache { } = new_cache , stmt } <- Cache . prepare ( stmt_cache , sql ) ,
81+ { :ok , stmt } <- Statement . bind_values ( stmt , Keyword . get ( opts , :bind , [ ] ) ) ,
82+ { :ok , rows } <- Statement . fetch_all ( stmt , :raw_list )
83+ do
84+ { :reply ,
85+ { :ok , % { rows: rows , columns: stmt . column_names , types: stmt . column_types } } ,
86+ { db , new_cache } }
87+ else
88+ err -> { :reply , err , { db , stmt_cache } }
89+ end
6390 end
6491
65- def handle_call ( { :query_rows , sql , opts } , _from , db ) do
66- rows = Sqlitex . query_rows ( db , sql , opts )
67- { :reply , rows , db }
92+ def handle_call ( { :prepare , sql } , _from , { db , stmt_cache } ) do
93+ with { % Cache { } = new_cache , stmt } <- Cache . prepare ( stmt_cache , sql )
94+ do
95+ { :reply ,
96+ { :ok , % { columns: stmt . column_names , types: stmt . column_types } } ,
97+ { db , new_cache } }
98+ else
99+ err -> { :reply , err , { db , stmt_cache } }
100+ end
68101 end
69102
70- def handle_call ( { :create_table , name , table_opts , cols } , _from , db ) do
103+ def handle_call ( { :create_table , name , table_opts , cols } , _from , { db , stmt_cache } ) do
71104 result = Sqlitex . create_table ( db , name , table_opts , cols )
72- { :reply , result , db }
105+ { :reply , result , { db , stmt_cache } }
73106 end
74107
75- def handle_cast ( :stop , db ) do
76- { :stop , :normal , db }
108+ def handle_cast ( :stop , { db , stmt_cache } ) do
109+ { :stop , :normal , { db , stmt_cache } }
77110 end
78111
79- def terminate ( _reason , db ) do
112+ def terminate ( _reason , { db , _stmt_cache } ) do
80113 Sqlitex . close ( db )
81114 :ok
82115 end
@@ -95,6 +128,10 @@ defmodule Sqlitex.Server do
95128 GenServer . call ( pid , { :query_rows , sql , opts } , timeout ( opts ) )
96129 end
97130
131+ def prepare ( pid , sql , opts \\ [ ] ) do
132+ GenServer . call ( pid , { :prepare , sql } , timeout ( opts ) )
133+ end
134+
98135 def create_table ( pid , name , table_opts \\ [ ] , cols ) do
99136 GenServer . call ( pid , { :create_table , name , table_opts , cols } )
100137 end
0 commit comments