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 }