1 module fdb.main;
2 
3 import
4     std.array,
5     std.concurrency,
6     std.conv,
7     std.exception,
8     std.format,
9     std.string;
10 
11 import
12     fdb.cluster,
13     fdb.error,
14     fdb.fdb_c,
15     fdb.fdb_c_options,
16     fdb.future,
17     fdb.networkoptions;
18 
19 private shared auto networkStarted = false;
20 private shared bool apiSelected    = false;
21 
22 private auto FBD_RUNTIME_API_VERSION = FDB_API_VERSION;
23 
24 void selectAPIVersion(const int apiVersion)
25 in
26 {
27     enforce(!apiSelected, "API version already selected");
28 }
29 body
30 {
31     auto err = fdb_select_api_version(apiVersion);
32     enforceError(err);
33 }
34 
35 auto networkThread()
36 in
37 {
38     assert(ownerTid != Tid.init);
39 }
40 body
41 {
42     auto err = fdb_run_network();
43     ownerTid.send(err);
44 }
45 
46 void startNetwork()
47 in
48 {
49     assert(!networkStarted);
50 }
51 body
52 {
53     if (networkStarted) return;
54 
55     if (!apiSelected)
56         selectAPIVersion(FBD_RUNTIME_API_VERSION);
57 
58     NetworkOptions.init;
59     auto err       = fdb_setup_network();
60     enforceError(err);
61 
62     spawn(&networkThread);
63     networkStarted = true;
64 }
65 
66 void stopNetwork()
67 in
68 {
69     assert(networkStarted);
70 }
71 body
72 {
73     if (!networkStarted) return;
74 
75     auto err       = fdb_stop_network();
76     enforceError(err);
77 
78     auto taskErr   = receiveOnly!fdb_error_t;
79     enforceError(taskErr);
80 
81     networkStarted = false;
82 }
83 
84 auto createCluster(const string clusterFilePath = null)
85 in
86 {
87     assert(networkStarted);
88 }
89 out (result)
90 {
91     assert(result !is null);
92 }
93 body
94 {
95     auto fh           = fdb_create_cluster(clusterFilePath.toStringz);
96     scope auto future = createFuture!VoidFuture(fh);
97     future.await;
98 
99     ClusterHandle ch;
100     auto err          = fdb_future_get_cluster(fh, &ch);
101     enforceError(err);
102 
103     return new shared Cluster(ch);
104 }
105 
106 auto open(const string clusterFilePath = null)
107 {
108     startNetwork;
109     auto cluster = createCluster(clusterFilePath);
110     auto db      = cluster.openDatabase;
111     return db;
112 }
113 
114 alias close = stopNetwork;