1 module fdb.database; 2 3 import 4 std.conv, 5 std.exception, 6 std.string, 7 std.traits; 8 9 import 10 fdb.cluster, 11 fdb.direct, 12 fdb.disposable, 13 fdb.error, 14 fdb.fdb_c, 15 fdb.fdb_c_options, 16 fdb.future, 17 fdb.range, 18 fdb.rangeinfo, 19 fdb.transaction; 20 21 shared class Database : IDirect, IDisposable 22 { 23 private const Cluster cluster; 24 private DatabaseHandle dbh; 25 26 private Transaction[] transactions; 27 28 invariant() 29 { 30 assert(cluster !is null); 31 } 32 33 this(DatabaseHandle dbh, const shared Cluster cluster) 34 in 35 { 36 enforce(cluster !is null, "cluster must be set"); 37 enforce(dbh !is null, "dbh must be set"); 38 } 39 body 40 { 41 this.dbh = cast(shared)dbh; 42 this.cluster = cluster; 43 } 44 45 ~this() 46 { 47 dispose; 48 } 49 50 void dispose() 51 { 52 if (!dbh) return; 53 54 fdb_database_destroy(cast(DatabaseHandle)dbh); 55 dbh = null; 56 } 57 58 auto createTransaction() 59 out (result) 60 { 61 assert(result !is null); 62 } 63 body 64 { 65 TransactionHandle th; 66 auto err = fdb_database_create_transaction( 67 cast(DatabaseHandle)dbh, 68 &th); 69 enforceError(err); 70 71 auto tr = new shared Transaction(th, this); 72 synchronized (this) 73 transactions ~= tr; 74 return tr; 75 } 76 77 /** 78 * Set the size of the client location cache. Raising this value can boost 79 * performance in very large databases where clients access data in a near- 80 * random pattern. Defaults to 100000. 81 * Parameter: (Int) Max location cache entries 82 */ 83 void setLocationCacheSize(const long value) const 84 { 85 setDatabaseOption(DatabaseOption.LOCATION_CACHE_SIZE, value); 86 } 87 88 /** 89 * Set the maximum number of watches allowed to be outstanding on a database 90 * connection. Increasing this number could result in increased resource 91 * usage. Reducing this number will not cancel any outstanding watches. 92 * Defaults to 10000 and cannot be larger than 1000000. 93 * Parameter: (Int) Max outstanding watches 94 */ 95 void setMaxWatches(const long value) const 96 { 97 setDatabaseOption(DatabaseOption.MAX_WATCHES, value); 98 } 99 100 /** 101 * Specify the machine ID that was passed to fdbserver processes running on 102 * the same machine as this client, for better location-aware load 103 * balancing. 104 * Parameter: (String) Hexadecimal ID 105 */ 106 void setMachineId(const string value) const 107 { 108 setDatabaseOption(DatabaseOption.MACHINE_ID, value); 109 } 110 111 /** 112 * Specify the datacenter ID that was passed to fdbserver processes running 113 * in the same datacenter as this client, for better location-aware load 114 * balancing. 115 * Parameter: (String) Hexadecimal ID 116 */ 117 void setDatacenterId(const string value) const 118 { 119 setDatabaseOption(DatabaseOption.DATACENTER_ID, value); 120 } 121 122 private void setDatabaseOption( 123 const DatabaseOption op, 124 const long value) const 125 { 126 const auto err = fdb_database_set_option( 127 cast(DatabaseHandle)dbh, 128 op, 129 cast(immutable(char)*)&value, 130 cast(int)value.sizeof); 131 enforceError(err); 132 } 133 134 private void setDatabaseOption( 135 const DatabaseOption op, 136 const string value) const 137 { 138 const auto err = fdb_database_set_option( 139 cast(DatabaseHandle)dbh, 140 op, 141 value.toStringz, 142 cast(int)value.length); 143 enforceError(err); 144 } 145 146 shared(Value) opIndex(const Key key) 147 { 148 auto tr = createTransaction(); 149 auto value = tr[key]; 150 tr.commit.await; 151 return value; 152 } 153 154 RecordRange opIndex(RangeInfo info) 155 { 156 auto tr = createTransaction(); 157 auto value = cast(RecordRange)tr[info]; 158 tr.commit.await; 159 return value; 160 } 161 162 inout(Value) opIndexAssign(inout(Value) value, const Key key) 163 { 164 auto tr = createTransaction(); 165 tr[key] = value; 166 tr.commit.await; 167 return value; 168 } 169 170 void clear(const Key key) 171 { 172 auto tr = createTransaction(); 173 tr.clear(key); 174 } 175 176 void clearRange(const RangeInfo info) 177 { 178 auto tr = createTransaction(); 179 tr.clearRange(info); 180 } 181 182 void run(SimpleWorkFunc func) 183 { 184 auto tr = createTransaction(); 185 tr.run(func); 186 }; 187 188 alias LoopFuture = shared FunctionFuture!( 189 retryLoop, ParameterTypeTuple!retryLoop); 190 191 LoopFuture doTransaction( 192 WorkFunc func, 193 VoidFutureCallback commitCallback) 194 { 195 auto tr = createTransaction(); 196 return tr.doTransaction(func, commitCallback); 197 }; 198 }