1 module hunt.database.driver.mysql.impl.MySQLConnectionImpl;
2 
3 import hunt.database.driver.mysql.impl.MySQLConnectionFactory;
4 import hunt.database.driver.mysql.impl.MySQLCollation;
5 
6 import hunt.database.driver.mysql.MySQLConnectOptions;
7 import hunt.database.driver.mysql.MySQLConnection;
8 import hunt.database.driver.mysql.MySQLSetOption;
9 import hunt.database.driver.mysql.impl.command.ChangeUserCommand;
10 import hunt.database.driver.mysql.impl.command.DebugCommand;
11 import hunt.database.driver.mysql.impl.command.InitDbCommand;
12 import hunt.database.driver.mysql.impl.command.PingCommand;
13 import hunt.database.driver.mysql.impl.command.ResetConnectionCommand;
14 import hunt.database.driver.mysql.impl.command.SetOptionCommand;
15 import hunt.database.driver.mysql.impl.command.StatisticsCommand;
16 import hunt.database.driver.mysql.MySQLUtil;
17 
18 import hunt.database.base.AsyncResult;
19 import hunt.database.base.Common;
20 import hunt.database.base.Transaction;
21 import hunt.database.base.impl.Connection;
22 import hunt.database.base.impl.command.CommandResponse;
23 import hunt.database.base.impl.command.PrepareStatementCommand;
24 import hunt.database.base.impl.NamedQueryDesc;
25 import hunt.database.base.impl.SqlConnectionImpl;
26 
27 import hunt.logging;
28 
29 import hunt.collection.List;
30 import hunt.concurrency.Future;
31 import hunt.concurrency.FuturePromise;
32 import hunt.Exceptions;
33 
34 
35 
36 alias MySQLNamedQueryDesc = NamedQueryDesc!("?", false);
37 
38 /**
39  * 
40  */
41 class MySQLConnectionImpl : SqlConnectionImpl!(MySQLConnectionImpl), MySQLConnection {
42 
43     static void connect(MySQLConnectOptions options, AsyncResultHandler!(MySQLConnection) handler) {
44         MySQLConnectionFactory client = new MySQLConnectionFactory(options);
45         version(HUNT_DB_DEBUG) trace("connecting ...");
46         client.connect( (ar) {
47             version(HUNT_DB_DEBUG) info("connection result: ", ar.succeeded());
48             if (ar.succeeded()) {
49                 DbConnection conn = ar.result();
50                 MySQLConnectionImpl p = new MySQLConnectionImpl(client, conn);
51                 conn.initHolder(p);
52                 if(handler !is null) {
53                     handler(succeededResult!(MySQLConnection)(p));
54                 }
55             } else if(handler !is null) {
56                 handler(failedResult!(MySQLConnection)(ar.cause()));
57             }
58         });
59     }
60 
61     private MySQLConnectionFactory factory;
62 
63     this(MySQLConnectionFactory factory, DbConnection conn) {
64         super(conn);
65 
66         this.factory = factory;
67     }
68 
69     override
70     void handleNotification(int processId, string channel, string payload) {
71         throw new UnsupportedOperationException();
72     }
73 
74     override
75     MySQLConnection ping(AsyncVoidHandler handler) {
76         PingCommand cmd = new PingCommand();
77         cmd.handler = (r) { handler(r); };
78         schedule(cmd);
79         return this;
80     }
81 
82     override
83     MySQLConnection specifySchema(string schemaName, AsyncVoidHandler handler) {
84         InitDbCommand cmd = new InitDbCommand(schemaName);
85         cmd.handler = (r) { handler(r); };
86         schedule(cmd);
87         return this;
88     }
89 
90     override
91     MySQLConnection getInternalStatistics(AsyncResultHandler!(string) handler) {
92         StatisticsCommand cmd = new StatisticsCommand();
93         cmd.handler = (r) { handler(r); };
94         schedule(cmd);
95         return this;
96     }
97 
98     override
99     MySQLConnection setOption(MySQLSetOption option, AsyncVoidHandler handler) {
100         SetOptionCommand cmd = new SetOptionCommand(option);
101         cmd.handler = (r) { handler(r); };
102         schedule(cmd);
103         return this;
104     }
105 
106     override
107     MySQLConnection resetConnection(AsyncVoidHandler handler) {
108         ResetConnectionCommand cmd = new ResetConnectionCommand();
109         cmd.handler = (r) { handler(r); };
110         schedule(cmd);
111         return this;
112     }
113 
114     override
115     MySQLConnection dumpDebug(AsyncVoidHandler handler) {
116         DebugCommand cmd = new DebugCommand();
117         cmd.handler = (r) { handler(r); };
118         schedule(cmd);
119         return this;
120     }
121 
122     override
123     MySQLConnection changeUser(MySQLConnectOptions options, AsyncVoidHandler handler) {
124         MySQLCollation collation;
125         try {
126             collation = MySQLCollation.valueOfName(options.getCollation());
127         } catch (IllegalArgumentException e) {
128             handler(failedResult!(Object)(e));
129             return this;
130         }
131         ChangeUserCommand cmd = new ChangeUserCommand(options.getUser(), options.getPassword(), 
132             options.getDatabase(), collation, options.getProperties());
133         cmd.handler = (r) { handler(r); };
134         schedule(cmd);
135         return this;
136     }
137 
138     // override protected AbstractNamedQueryDesc getNamedQueryDesc(string sql) {
139     //     return new MySQLNamedQueryDesc(sql);
140     // }
141 
142     // protected AbstractNamedQueryDesc getNamedQueryDesc(string sql) {
143     //     throw new NotImplementedException("getNamedQueryDesc");
144     // }
145 
146     Future!NamedQuery prepareNamedQueryAsync(string sql) {
147         version(HUNT_DB_DEBUG) trace(sql);
148         auto f = new FuturePromise!NamedQuery("NamedQuery");
149         AbstractNamedQueryDesc queryDesc = new MySQLNamedQueryDesc(sql);
150 
151         scheduleThen!(PreparedStatement)(new PrepareStatementCommand(queryDesc.getSql()), 
152             (CommandResponse!PreparedStatement ar) {
153                 if (ar.succeeded()) {
154                     NamedQueryImpl queryImpl = new MySQLNamedQueryImpl(conn, ar.result(), queryDesc);
155                     f.succeeded(queryImpl);
156                 } else {
157                     f.failed(ar.cause()); 
158                 }
159             }
160         );
161         
162         return f;
163     }
164 
165     NamedQuery prepareNamedQuery(string sql) {
166         auto f = prepareNamedQueryAsync(sql);
167         version(HUNT_DEBUG) warning("try to get a result");
168         import core.time;
169         return f.get(awaittingTimeout);
170     }       
171 
172     string escapeIdentifier(string identifier) {
173 // TODO: Tasks pending completion -@zxp at Fri, 20 Sep 2019 02:44:54 GMT        
174 // 
175         return identifier;
176     }
177 
178     string escapeLiteral(string literal) {
179         return MySQLUtil.escapeLiteral(literal);
180     }      
181 }
182 
183 
184 import hunt.database.driver.mysql.impl.codec.MySQLRowDesc;
185 
186 import hunt.database.base.impl.NamedQueryDesc;
187 import hunt.database.base.impl.NamedQueryImpl;
188 import hunt.database.base.impl.PreparedQueryImpl;
189 import hunt.database.base.impl.RowDesc;
190 
191 import hunt.database.base.impl.ArrayTuple;
192 import hunt.database.base.impl.Connection;
193 import hunt.database.base.impl.ParamDesc;
194 import hunt.database.base.impl.PreparedStatement;
195 
196 import hunt.database.base.PreparedQuery;
197 import hunt.database.base.RowSet;
198 import std.variant;
199 
200 /**
201  * 
202  */
203 class MySQLNamedQueryImpl : NamedQueryImpl {
204 
205     this(DbConnection conn, PreparedStatement ps, AbstractNamedQueryDesc queryDesc) {
206         super(conn, ps, queryDesc);
207     }
208 
209     void setParameter(string name, Variant value) {
210         version(HUNT_DEBUG) {
211             auto itemPtr = name in _parameters;
212             if(itemPtr !is null) {
213                 warning("% will be overwrited with %s", name, value.toString());
214             }
215         }
216 
217 
218         // TODO: Tasks pending completion -@zhangxueping at 2019-10-01T13:35:23+08:00
219         // validate the type of parameter
220         // hunt.database.driver.mysql.impl.codec.ColumnDefinition;
221 
222         // getPreparedStatement().paramDesc();
223 
224         // MySQLRowDesc rowDesc = cast(MySQLRowDesc)getPreparedStatement().rowDesc();
225         // warning(rowDesc.toString());
226 
227         // ParamDesc pd = getPreparedStatement().paramDesc();
228         // warning(pd.toString());
229 
230         _parameters[name] = value;
231     }
232 
233 }