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.SqlResultBuilder;
19 
20 import hunt.database.base.impl.QueryResultHandler;
21 import hunt.database.base.impl.RowDesc;
22 
23 import hunt.database.base.SqlResult;
24 import hunt.database.base.AsyncResult;
25 
26 import hunt.logging;
27 import hunt.Functions;
28 
29 import std.variant;
30 
31 /**
32  * A query result handler for building a {@link SqlResult}.
33  */
34 class SqlResultBuilder(T, R, L) : QueryResultHandler!(T) { // , Handler!(AsyncResult!(bool))
35 
36     // R extends SqlResultBase!(T, R)
37     // L extends SqlResult!(T)
38 
39     private AsyncResultHandler!(L) handler;
40     private Function!(T, R) factory;
41     private R first;
42     private bool suspended;
43 
44     this(Function!(T, R) factory, AsyncResultHandler!(L) handler) {
45         this.factory = factory;
46         this.handler = handler;
47     }
48 
49     override
50     void handleResult(int updatedCount, int size, RowDesc desc, T result) {
51         R r = factory(result);
52         r._updated = updatedCount;
53         r._size = size;
54         r._columnNames = desc !is null ? desc.columnNames() : null;
55         handleResult(r);
56     }
57 
58     private void handleResult(R result) {
59         if (first is null) {
60             first = result;
61         } else {
62             R h = first;
63             while (h.next !is null) {
64                 h = h.next;
65             }
66             h.next = result;
67         }
68     }
69 
70     // override
71     void handle(AsyncResult!(bool) res) {
72         suspended = res.succeeded() && res.result();
73 
74         version(HUNT_DB_DEBUG) {
75             tracef("succeeded: %s, result: %s", res.succeeded(), res.result());
76         }
77 
78         if(handler !is null) {
79             handler(res.map!(L)(first)); // AsyncResult!(RowSetImpl)
80         }
81     }
82 
83     void addProperty(string name, ref Variant value) {
84         if(first !is null) {
85             R r = first;
86             while (r.next !is null) {
87                 r = r.next;
88             }
89 
90             r.properties[name] = value;
91         }
92     }
93 
94     bool isSuspended() {
95         return suspended;
96     }
97 }