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.impl.CursorImpl;
19 
20 import hunt.database.base.impl.PreparedQueryImpl;
21 import hunt.database.base.impl.RowSetImpl;
22 import hunt.database.base.impl.SqlResultBuilder;
23 import hunt.database.base.impl.command.CommandResponse;
24 
25 import hunt.database.base.AsyncResult;
26 import hunt.database.base.Common;
27 import hunt.database.base.Cursor;
28 import hunt.database.base.RowSet;
29 import hunt.database.base.Tuple;
30 
31 import hunt.Exceptions;
32 import hunt.logging;
33 import hunt.Object;
34 
35 import std.range;
36 import std.uuid;
37 
38 /**
39  * @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
40  */
41 class CursorImpl : Cursor {
42 
43     private PreparedQueryImpl ps;
44     private Tuple params;
45 
46     private string id;
47     private bool closed;
48     private SqlResultBuilder!(RowSet, RowSetImpl, RowSet) result;
49 
50     this(PreparedQueryImpl ps, Tuple params) {
51         this.ps = ps;
52         this.params = params;
53     }
54 
55     override
56     bool hasMore() {
57         if (result is null) {
58             throw new IllegalStateException("No current cursor read");
59         }
60         return result.isSuspended();
61     }
62 
63     override
64     void read(int count, RowSetHandler handler) {
65         if (id.empty) {
66             id = randomUUID().toString();
67             result = new SqlResultBuilder!(RowSet, RowSetImpl, RowSet)(RowSetImpl.FACTORY, handler);
68             ps.execute!(RowSet)(params, count, id, false, false, result, 
69                 (CommandResponse!bool r) {  result.handle(r); }
70             );
71         } else if (result.isSuspended()) {
72             result = new SqlResultBuilder!(RowSet, RowSetImpl, RowSet)(RowSetImpl.FACTORY, handler);
73             ps.execute!(RowSet)(params, count, id, true, false, result, 
74                 (CommandResponse!bool r) {  result.handle(r); }
75             );
76         } else {
77             throw new IllegalStateException();
78         }
79     }
80 
81     override
82     void close(AsyncVoidHandler completionHandler) {
83         if (!closed) {
84             closed = true;
85             version(HUNT_DB_DEBUG_MORE) infof("id: %s", id);
86             if (id.empty) { 
87                 if(completionHandler !is null)
88                     completionHandler(succeededResult!(Object)(null)); // Future.succeededFuture()
89             } else {
90                 string id = this.id;
91                 this.id = null;
92                 result = null;
93                 ps.closeCursor(id, completionHandler);
94             }
95         }
96     }
97 }