1 // Written in D programming language 2 /** 3 * Part of asynchronous pool realization. 4 * 5 * Copyright: © 2014 DSoftOut 6 * License: Subject to the terms of the MIT license, as written in the included LICENSE file. 7 * Authors: NCrashed <ncrashed@gmail.com> 8 */ 9 module pgator.db.async.transaction; 10 11 import std.conv; 12 import std.exception; 13 14 import pgator.db.pool; 15 16 private T min(T)(T a, T b) { return a < b ? a : b; } 17 18 /** 19 * Handles all data that is need to perform SQL transaction: queries, parameters, 20 * info where to put parameters and local enviroment variables. 21 */ 22 class Transaction : IConnectionPool.ITransaction 23 { 24 this(string[] commands, string[] params, uint[] argnums, string[string] vars, bool[] oneRowConstraints) immutable 25 { 26 this.commands = commands.idup; 27 this.params = params.idup; 28 this.argnums = argnums.idup; 29 string[string] temp = vars.dup; 30 this.vars = assumeUnique(temp); 31 this.oneRowConstraints = oneRowConstraints.idup; 32 } 33 34 override bool opEquals(Object o) nothrow 35 { 36 auto b = cast(Transaction)o; 37 if(b is null) return false; 38 39 return commands == b.commands && params == b.params && argnums == b.argnums && vars == b.vars && oneRowConstraints == b.oneRowConstraints; 40 } 41 42 override hash_t toHash() nothrow @trusted 43 { 44 hash_t toHashArr(T)(immutable T[] arr) nothrow 45 { 46 hash_t h; 47 auto hashFunc = &(typeid(T).getHash); 48 foreach(elem; arr) h += hashFunc(&elem); 49 return h; 50 } 51 52 hash_t toHashAss(T)(immutable T[T] arr) nothrow 53 { 54 hash_t h; 55 scope(failure) return 0; 56 auto hashFunc = &(typeid(T).getHash); 57 foreach(key, val; arr) h += hashFunc(&key) + hashFunc(&val); 58 return h; 59 } 60 61 return toHashArr(commands) + toHashArr(params) + toHashArr(argnums) + toHashAss(vars) + toHashArr(oneRowConstraints); 62 } 63 64 void toString(scope void delegate(const(char)[]) sink) const 65 { 66 if(commands.length == 1) 67 { 68 sink("Command: "); 69 sink(commands[0]); 70 if(params.length != 0) 71 { 72 sink("\n"); 73 sink(text("With params: ", params)); 74 } 75 sink("\n"); 76 sink(text("One row: ",oneRowConstraints[0])); 77 if(vars.length != 0) sink("\n"); 78 } 79 else 80 { 81 sink("Commands: \n"); 82 size_t j = 0; 83 foreach(immutable i, command; commands) 84 { 85 sink(text(i, ": ", command)); 86 sink("\n"); 87 if(i >= argnums.length) continue; 88 89 if(params.length != 0) 90 { 91 size_t k = min(j+argnums[i], params.length); 92 sink(text("With params: ", params[j .. k])); 93 } 94 sink("\n"); 95 sink(text("One row: ",oneRowConstraints[i])); 96 if(i != commands.length-1) sink("\n"); 97 j += argnums[i]; 98 } 99 if(vars.length != 0) sink("\n"); 100 } 101 102 if(vars.length != 0) 103 { 104 sink("Variables: \n"); 105 size_t i = 0; 106 foreach(key, value; vars) 107 { 108 sink(text(key, " : ", value)); 109 if(i++ != vars.length - 1) sink("\n"); 110 } 111 } 112 } 113 114 immutable string[] commands; 115 immutable string[] params; 116 immutable uint[] argnums; 117 immutable string[string] vars; 118 immutable bool[] oneRowConstraints; 119 }