1 /*
2  * Copyright (C) 2019, HuntLabs
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 module hunt.database.base.PreparedQuery;
19 
20 import hunt.database.base.AsyncResult;
21 import hunt.database.base.Common;
22 import hunt.database.base.Cursor;
23 import hunt.database.base.RowSet;
24 import hunt.database.base.impl.ArrayTuple;
25 import hunt.database.base.Tuple;
26 
27 import hunt.database.base.impl.PreparedStatement;
28 
29 import hunt.collection.List;
30 
31 alias PreparedQueryHandler = AsyncResultHandler!(PreparedQuery);
32 alias PreparedQueryAsyncResult = AsyncResult!PreparedQuery;
33 
34 /**
35  * A prepared query.
36  *
37  * @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
38  */
39 interface PreparedQuery {
40 
41     PreparedStatement getPreparedStatement();
42 
43     /**
44      * Calls {@link #execute(Tuple, Handler)} with an empty tuple argument.
45      */
46     PreparedQuery execute(RowSetHandler handler);
47 
48     /**
49      * Calls {@link #execute(Tuple, Collector, Handler)} with an empty tuple argument.
50      */
51     // default <R> PreparedQuery execute(Collector<Row, ?, R> collector, Handler!(AsyncResult!(SqlResult!(R))) handler) {
52     //     return execute(ArrayTuple.EMPTY, collector, handler);
53     // }
54 
55     /**
56      * Create a cursor with the provided {@code arguments}.
57      *
58      * @param args the list of arguments
59      * @return the query
60      */
61     PreparedQuery execute(Tuple args, RowSetHandler handler);
62 
63     /**
64      * Create a cursor with the provided {@code arguments}.
65      *
66      * @param args the list of arguments
67      * @param collector the collector
68      * @return the query
69      */
70     // <R> PreparedQuery execute(Tuple args, Collector<Row, ?, R> collector, Handler!(AsyncResult!(SqlResult!(R))) handler);
71 
72     /**
73      * @return create a query cursor with a {@code fetch} size and empty arguments
74      */
75     Cursor cursor();
76 
77     /**
78      * Create a cursor with the provided {@code arguments}.
79      *
80      * @param args the list of arguments
81      * @return the query
82      */
83     Cursor cursor(Tuple args);
84 
85     /**
86      * Execute the prepared query with a cursor and createStream the result. The createStream opens a cursor
87      * with a {@code fetch} size to fetch the results.
88      * <p/>
89      * Note: this requires to be in a transaction, since cursors require it.
90      *
91      * @param fetch the cursor fetch size
92      * @param args the prepared query arguments
93      * @return the createStream
94      */
95     // RowStream!(Row) createStream(int fetch, Tuple args);
96 
97     /**
98      * Execute a batch.
99      *
100      * @param argsList the list of tuple for the batch
101      * @return the createBatch
102      */
103     PreparedQuery batch(List!(Tuple) argsList, RowSetHandler handler);
104 
105     /**
106      * Execute a batch.
107      *
108      * @param argsList the list of tuple for the batch
109      * @param collector the collector
110      * @return the createBatch
111      */
112     // <R> PreparedQuery batch(List!(Tuple) argsList, Collector<Row, ?, R> collector, Handler!(AsyncResult!(SqlResult!(R))) handler);
113 
114     /**
115      * Close the prepared query and release its resources.
116      */
117     void close();
118 
119     /**
120      * Like {@link #close()} but notifies the {@code completionHandler} when it's closed.
121      */
122     void close(AsyncVoidHandler completionHandler);
123 
124 }
125 
126 
127 /**
128  * This class wraps around a {@link PreparedStatement} and allows the programmer to set parameters by name instead of by
129  * index. This eliminates any confusion as to which parameter index represents what. This also means that rearranging
130  * the SQL statement or adding a parameter doesn't involve renumbering your indices. Code such as this:
131  * 
132  * 
133  * Connection con=getConnection(); String query="select * from my_table where name=? or address=?"; PreparedStatement
134  * p=con.prepareStatement(query); p.setString(1, "bob"); p.setString(2, "123 terrace ct"); ResultSet
135  * rs=p.executeQuery();
136  * 
137  * can be replaced with:
138  * 
139  * Connection con=getConnection(); String query="select * from my_table where name=:name or address=:address";
140  * NamedParameterStatement p=new NamedParameterStatement(con, query); p.setString("name", "bob"); p.setString("address",
141  * "123 terrace ct"); ResultSet rs=p.executeQuery();
142  * 
143  * Sourced from JavaWorld Article @ http://www.javaworld.com/javaworld/jw-04-2007/jw-04-jdbc.html
144  * 
145  */
146 interface NamedQuery : PreparedQuery {
147 
148     import std.variant;
149     void setParameter(string name, Variant value);
150     
151     final void setParameter(R)(string name, R value) if(!is(R == Variant)) {
152         setParameter(name, Variant(value));
153     }
154 }