CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/client/query.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import * as message from "@cocalc/util/message";
7
import { is_array } from "@cocalc/util/misc";
8
import { validate_client_query } from "@cocalc/util/schema-validate";
9
import { CB } from "@cocalc/util/types/database";
10
11
declare const $: any; // jQuery
12
13
export class QueryClient {
14
private client: any;
15
16
constructor(client: any) {
17
this.client = client;
18
}
19
20
private async call(message: object, timeout: number): Promise<any> {
21
return await this.client.async_call({
22
message,
23
timeout,
24
allow_post: false, // since that would happen via this.post_query
25
});
26
}
27
28
// This works like a normal async function when
29
// opts.cb is NOT specified. When opts.cb is specified,
30
// it works like a cb and returns nothing. For changefeeds
31
// you MUST specify opts.cb, but can always optionally do so.
32
public async query(opts: {
33
query: object;
34
changes?: boolean;
35
options?: object[]; // if given must be an array of objects, e.g., [{limit:5}]
36
standby?: boolean; // if true and use HTTP post, then will use standby server (so must be read only)
37
timeout?: number; // default: 30
38
no_post?: boolean; // DEPRECATED -- didn't turn out to be worth it.
39
ignore_response?: boolean; // if true, be slightly efficient by not waiting for any response or
40
// error (just assume it worked; don't care about response)
41
cb?: CB; // used for changefeed outputs if changes is true
42
}): Promise<any> {
43
if (opts.options != null && !is_array(opts.options)) {
44
// should never happen...
45
throw Error("options must be an array");
46
}
47
if (opts.changes && opts.cb == null) {
48
throw Error("for changefeed, must specify opts.cb");
49
}
50
51
const err = validate_client_query(opts.query, this.client.account_id);
52
if (err) {
53
throw Error(err);
54
}
55
const mesg = message.query({
56
query: opts.query,
57
options: opts.options,
58
changes: opts.changes,
59
multi_response: !!opts.changes,
60
});
61
if (opts.timeout == null) {
62
opts.timeout = 30;
63
}
64
if (mesg.multi_response) {
65
if (opts.cb == null) {
66
throw Error("changefeed requires cb callback");
67
}
68
this.client.call({
69
allow_post: false,
70
message: mesg,
71
error_event: true,
72
timeout: opts.timeout,
73
cb: opts.cb,
74
});
75
} else {
76
if (opts.cb != null) {
77
try {
78
const result = await this.call(mesg, opts.timeout);
79
opts.cb(undefined, result);
80
} catch (err) {
81
opts.cb(typeof err == "string" ? err : err.message ?? err);
82
}
83
} else {
84
return await this.call(mesg, opts.timeout);
85
}
86
}
87
}
88
89
public async cancel(id: string): Promise<void> {
90
await this.call(message.query_cancel({ id }), 30);
91
}
92
}
93
94