1 #include "ejdb2.h"
2 #include "ejdb2cfg.h"
3
4 #include <fio_cli.h>
5 #include <stdio.h>
6 #include <errno.h>
7 #include <ctype.h>
8
9 EJDB db; // -V707
10 EJDB_OPTS opts;
11
main(int argc,char const * argv[])12 int main(int argc, char const *argv[]) {
13 iwrc rc = 0;
14 fio_cli_start(argc, argv, 0, 0,
15 "EJDB " EJDB2_VERSION " standalone HTTP REST/Websocket server. http://ejdb.org\n",
16 FIO_CLI_STRING("--file -f Database file path. Default: ejdb2.db"),
17 FIO_CLI_INT("--port -p HTTP port number listen to. Default: 9191"),
18 FIO_CLI_STRING("--bind -b Address server listen. Default: localhost"),
19 FIO_CLI_STRING("--access -a Server access token matched to 'X-Access-Token' HTTP header value.\n"
20 "If token prefixed by '@' it will be treated as file."),
21 FIO_CLI_BOOL("--trunc -t Cleanup existing database file on open"),
22 FIO_CLI_BOOL("--wal -w Use write ahead logging (WAL). Must be set for data durability."),
23 FIO_CLI_BOOL("--cors Enable Cross-Origin Resource Sharing (CORS)."),
24 FIO_CLI_PRINT_HEADER("Advanced options"),
25 FIO_CLI_INT(
26 "--sbz Max sorting buffer size. If exceeded, an overflow temp file for data will be created. "
27 "Default: 16777216, min: 1048576"),
28 FIO_CLI_INT("--dsz Initial size of buffer to process/store document on queries. "
29 "Preferable average size of document. "
30 "Default: 65536, min: 16384"),
31 FIO_CLI_INT("--bsz Max HTTP/WS API document body size. " "Default: 67108864, min: 524288"),
32 FIO_CLI_BOOL("--trylock Fail if database is locked by another process."
33 " If not set, current process will wait for lock release")
34
35 );
36 fio_cli_set_default("--file", "ejdb2.db");
37 fio_cli_set_default("-f", "ejdb2.db");
38 fio_cli_set_default("--port", "9191");
39 fio_cli_set_default("-p", "9191");
40 fio_cli_set_default("--sbz", "16777216");
41 fio_cli_set_default("--dsz", "65536");
42 fio_cli_set_default("--bsz", "67108864");
43
44 char access_token_buf[255];
45 const char *access_token = fio_cli_get("-a");
46 if (access_token && (*access_token == '@')) {
47 access_token = access_token + 1;
48 FILE *f = fopen(access_token, "r");
49 if (!f) {
50 rc = iwrc_set_errno(IW_ERROR_IO_ERRNO, errno);
51 goto finish;
52 }
53 size_t n = fread(access_token_buf, 1, sizeof(access_token_buf), f);
54 if ((n == 0) || (n == sizeof(access_token_buf))) {
55 fclose(f);
56 rc = IW_ERROR_INVALID_VALUE;
57 iwlog_error("Invalid access token from %s", access_token);
58 goto finish;
59 }
60 access_token_buf[n] = '\0';
61 for (int i = 0; i < n; ++i) {
62 if (isspace(access_token_buf[i])) {
63 access_token_buf[i] = '\0';
64 break;
65 }
66 }
67 fclose(f);
68 access_token = access_token_buf;
69 } else if (access_token && (strlen(access_token) >= sizeof(access_token_buf))) {
70 rc = IW_ERROR_INVALID_VALUE;
71 iwlog_error2("Invalid access token");
72 goto finish;
73 }
74
75 EJDB_OPTS ov = {
76 .kv = {
77 .path = fio_cli_get("-f"),
78 .oflags = fio_cli_get_i("-t") ? IWKV_TRUNC : 0,
79 .file_lock_fail_fast = fio_cli_get_bool("--trylock")
80 },
81 .no_wal = !fio_cli_get_i("-w"),
82 .sort_buffer_sz = fio_cli_get_i("--sbz"),
83 .document_buffer_sz = fio_cli_get_i("--dsz"),
84 .http = {
85 .enabled = true,
86 .blocking = true,
87 .port = fio_cli_get_i("-p"),
88 .bind = fio_cli_get("-b"),
89 .access_token = access_token,
90 .max_body_size = fio_cli_get_i("--bsz"),
91 .cors = fio_cli_get_bool("--cors")
92 }
93 };
94 memcpy(&opts, &ov, sizeof(ov));
95
96 rc = ejdb_open(&opts, &db);
97 RCGO(rc, finish);
98 IWRC(ejdb_close(&db), rc);
99 finish:
100 fio_cli_end();
101 if (rc) {
102 iwlog_ecode_error3(rc);
103 }
104 return rc ? 1 : 0;
105 }
106