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.context, 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 : IDatabaseContext, 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 private auto createTransactionImpl() 59 { 60 TransactionHandle th; 61 auto err = fdb_database_create_transaction( 62 cast(DatabaseHandle)dbh, 63 &th); 64 enforceError(err); 65 66 auto tr = new shared Transaction(th, this); 67 return tr; 68 } 69 70 auto createTransaction() 71 out (result) 72 { 73 assert(result !is null); 74 } 75 body 76 { 77 auto tr = createTransactionImpl(); 78 synchronized (this) 79 transactions ~= tr; 80 return tr; 81 } 82 83 /** 84 * Set the size of the client location cache. Raising this value can boost 85 * performance in very large databases where clients access data in a near- 86 * random pattern. Defaults to 100000. 87 * Parameter: (Int) Max location cache entries 88 */ 89 void setLocationCacheSize(in long value) const 90 { 91 setDatabaseOption(DatabaseOption.LOCATION_CACHE_SIZE, value); 92 } 93 94 /** 95 * Set the maximum number of watches allowed to be outstanding on a database 96 * connection. Increasing this number could result in increased resource 97 * usage. Reducing this number will not cancel any outstanding watches. 98 * Defaults to 10000 and cannot be larger than 1000000. 99 * Parameter: (Int) Max outstanding watches 100 */ 101 void setMaxWatches(in long value) const 102 { 103 setDatabaseOption(DatabaseOption.MAX_WATCHES, value); 104 } 105 106 /** 107 * Specify the machine ID that was passed to fdbserver processes running on 108 * the same machine as this client, for better location-aware load 109 * balancing. 110 * Parameter: (String) Hexadecimal ID 111 */ 112 void setMachineId(in string value) const 113 { 114 setDatabaseOption(DatabaseOption.MACHINE_ID, value); 115 } 116 117 /** 118 * Specify the datacenter ID that was passed to fdbserver processes running 119 * in the same datacenter as this client, for better location-aware load 120 * balancing. 121 * Parameter: (String) Hexadecimal ID 122 */ 123 void setDatacenterId(in string value) const 124 { 125 setDatabaseOption(DatabaseOption.DATACENTER_ID, value); 126 } 127 128 private void setDatabaseOption(in DatabaseOption op, in long value) const 129 { 130 const auto err = fdb_database_set_option( 131 cast(DatabaseHandle)dbh, 132 op, 133 cast(immutable(char)*)&value, 134 cast(int)value.sizeof); 135 enforceError(err); 136 } 137 138 private void setDatabaseOption(in DatabaseOption op, in string value) const 139 { 140 const auto err = fdb_database_set_option( 141 cast(DatabaseHandle)dbh, 142 op, 143 value.toStringz, 144 cast(int)value.length); 145 enforceError(err); 146 } 147 148 shared(Value) opIndex(in Key key) 149 { 150 scope auto tr = createTransactionImpl(); 151 auto value = tr[key]; 152 tr.commit; 153 return value; 154 } 155 156 RecordRange opIndex(RangeInfo info) 157 { 158 auto tr = createTransaction(); 159 auto value = cast(RecordRange)tr[info]; 160 tr.commit; 161 return value; 162 } 163 164 inout(Value) opIndexAssign(inout(Value) value, in Key key) 165 { 166 scope auto tr = createTransactionImpl(); 167 tr[key] = value; 168 tr.commit; 169 return value; 170 } 171 172 void clear(in Key key) 173 { 174 scope auto tr = createTransactionImpl(); 175 tr.clear(key); 176 tr.commit; 177 } 178 179 void clearRange(in RangeInfo info) 180 { 181 scope auto tr = createTransactionImpl(); 182 tr.clearRange(info); 183 tr.commit; 184 } 185 186 void run(in WorkFunc func) 187 { 188 scope auto tr = createTransactionImpl(); 189 tr.run(func); 190 } 191 192 auto runAsync(in WorkFunc func, in VoidFutureCallback commitCallback) 193 { 194 auto tr = createTransaction(); 195 return tr.runAsync(func, commitCallback); 196 } 197 }