camusdb 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +950 -0
  3. package/dist/auth/credentials.d.ts +30 -0
  4. package/dist/auth/credentials.d.ts.map +1 -0
  5. package/dist/auth/credentials.js +23 -0
  6. package/dist/auth/credentials.js.map +1 -0
  7. package/dist/auth/login-client.d.ts +37 -0
  8. package/dist/auth/login-client.d.ts.map +1 -0
  9. package/dist/auth/login-client.js +8 -0
  10. package/dist/auth/login-client.js.map +1 -0
  11. package/dist/auth/rest-login-client.d.ts +17 -0
  12. package/dist/auth/rest-login-client.d.ts.map +1 -0
  13. package/dist/auth/rest-login-client.js +71 -0
  14. package/dist/auth/rest-login-client.js.map +1 -0
  15. package/dist/auth/token-provider.d.ts +123 -0
  16. package/dist/auth/token-provider.d.ts.map +1 -0
  17. package/dist/auth/token-provider.js +209 -0
  18. package/dist/auth/token-provider.js.map +1 -0
  19. package/dist/backup.d.ts +98 -0
  20. package/dist/backup.d.ts.map +1 -0
  21. package/dist/backup.js +153 -0
  22. package/dist/backup.js.map +1 -0
  23. package/dist/cache.d.ts +90 -0
  24. package/dist/cache.d.ts.map +1 -0
  25. package/dist/cache.js +121 -0
  26. package/dist/cache.js.map +1 -0
  27. package/dist/client.d.ts +406 -0
  28. package/dist/client.d.ts.map +1 -0
  29. package/dist/client.js +724 -0
  30. package/dist/client.js.map +1 -0
  31. package/dist/column-type.d.ts +33 -0
  32. package/dist/column-type.d.ts.map +1 -0
  33. package/dist/column-type.js +50 -0
  34. package/dist/column-type.js.map +1 -0
  35. package/dist/column-value.d.ts +77 -0
  36. package/dist/column-value.d.ts.map +1 -0
  37. package/dist/column-value.js +60 -0
  38. package/dist/column-value.js.map +1 -0
  39. package/dist/config.d.ts +181 -0
  40. package/dist/config.d.ts.map +1 -0
  41. package/dist/config.js +315 -0
  42. package/dist/config.js.map +1 -0
  43. package/dist/connection-string.d.ts +45 -0
  44. package/dist/connection-string.d.ts.map +1 -0
  45. package/dist/connection-string.js +170 -0
  46. package/dist/connection-string.js.map +1 -0
  47. package/dist/endpoint-pool.d.ts +70 -0
  48. package/dist/endpoint-pool.d.ts.map +1 -0
  49. package/dist/endpoint-pool.js +120 -0
  50. package/dist/endpoint-pool.js.map +1 -0
  51. package/dist/error-codes.d.ts +44 -0
  52. package/dist/error-codes.d.ts.map +1 -0
  53. package/dist/error-codes.js +43 -0
  54. package/dist/error-codes.js.map +1 -0
  55. package/dist/errors.d.ts +24 -0
  56. package/dist/errors.d.ts.map +1 -0
  57. package/dist/errors.js +33 -0
  58. package/dist/errors.js.map +1 -0
  59. package/dist/hlc.d.ts +19 -0
  60. package/dist/hlc.d.ts.map +1 -0
  61. package/dist/hlc.js +11 -0
  62. package/dist/hlc.js.map +1 -0
  63. package/dist/index.d.ts +55 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +51 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/json.d.ts +41 -0
  68. package/dist/json.d.ts.map +1 -0
  69. package/dist/json.js +345 -0
  70. package/dist/json.js.map +1 -0
  71. package/dist/object-id.d.ts +39 -0
  72. package/dist/object-id.d.ts.map +1 -0
  73. package/dist/object-id.js +99 -0
  74. package/dist/object-id.js.map +1 -0
  75. package/dist/options.d.ts +77 -0
  76. package/dist/options.d.ts.map +1 -0
  77. package/dist/options.js +68 -0
  78. package/dist/options.js.map +1 -0
  79. package/dist/prepared/binder.d.ts +20 -0
  80. package/dist/prepared/binder.d.ts.map +1 -0
  81. package/dist/prepared/binder.js +32 -0
  82. package/dist/prepared/binder.js.map +1 -0
  83. package/dist/prepared/policy.d.ts +81 -0
  84. package/dist/prepared/policy.d.ts.map +1 -0
  85. package/dist/prepared/policy.js +164 -0
  86. package/dist/prepared/policy.js.map +1 -0
  87. package/dist/query-stream.d.ts +55 -0
  88. package/dist/query-stream.d.ts.map +1 -0
  89. package/dist/query-stream.js +94 -0
  90. package/dist/query-stream.js.map +1 -0
  91. package/dist/result-set.d.ts +62 -0
  92. package/dist/result-set.d.ts.map +1 -0
  93. package/dist/result-set.js +100 -0
  94. package/dist/result-set.js.map +1 -0
  95. package/dist/retry.d.ts +38 -0
  96. package/dist/retry.d.ts.map +1 -0
  97. package/dist/retry.js +93 -0
  98. package/dist/retry.js.map +1 -0
  99. package/dist/routing/advice.d.ts +63 -0
  100. package/dist/routing/advice.d.ts.map +1 -0
  101. package/dist/routing/advice.js +61 -0
  102. package/dist/routing/advice.js.map +1 -0
  103. package/dist/routing/route-cache.d.ts +53 -0
  104. package/dist/routing/route-cache.d.ts.map +1 -0
  105. package/dist/routing/route-cache.js +123 -0
  106. package/dist/routing/route-cache.js.map +1 -0
  107. package/dist/routing/router.d.ts +53 -0
  108. package/dist/routing/router.d.ts.map +1 -0
  109. package/dist/routing/router.js +89 -0
  110. package/dist/routing/router.js.map +1 -0
  111. package/dist/row-source.d.ts +48 -0
  112. package/dist/row-source.d.ts.map +1 -0
  113. package/dist/row-source.js +35 -0
  114. package/dist/row-source.js.map +1 -0
  115. package/dist/runtime.d.ts +58 -0
  116. package/dist/runtime.d.ts.map +1 -0
  117. package/dist/runtime.js +137 -0
  118. package/dist/runtime.js.map +1 -0
  119. package/dist/shared-registry.d.ts +32 -0
  120. package/dist/shared-registry.d.ts.map +1 -0
  121. package/dist/shared-registry.js +48 -0
  122. package/dist/shared-registry.js.map +1 -0
  123. package/dist/sql-syntax.d.ts +44 -0
  124. package/dist/sql-syntax.d.ts.map +1 -0
  125. package/dist/sql-syntax.js +83 -0
  126. package/dist/sql-syntax.js.map +1 -0
  127. package/dist/statements.d.ts +15 -0
  128. package/dist/statements.d.ts.map +1 -0
  129. package/dist/statements.js +90 -0
  130. package/dist/statements.js.map +1 -0
  131. package/dist/transaction.d.ts +117 -0
  132. package/dist/transaction.d.ts.map +1 -0
  133. package/dist/transaction.js +204 -0
  134. package/dist/transaction.js.map +1 -0
  135. package/dist/transport/authenticating-transport.d.ts +63 -0
  136. package/dist/transport/authenticating-transport.d.ts.map +1 -0
  137. package/dist/transport/authenticating-transport.js +119 -0
  138. package/dist/transport/authenticating-transport.js.map +1 -0
  139. package/dist/transport/branch-statements.d.ts +39 -0
  140. package/dist/transport/branch-statements.d.ts.map +1 -0
  141. package/dist/transport/branch-statements.js +74 -0
  142. package/dist/transport/branch-statements.js.map +1 -0
  143. package/dist/transport/error-text.d.ts +26 -0
  144. package/dist/transport/error-text.d.ts.map +1 -0
  145. package/dist/transport/error-text.js +75 -0
  146. package/dist/transport/error-text.js.map +1 -0
  147. package/dist/transport/grpc/batcher.d.ts +127 -0
  148. package/dist/transport/grpc/batcher.d.ts.map +1 -0
  149. package/dist/transport/grpc/batcher.js +399 -0
  150. package/dist/transport/grpc/batcher.js.map +1 -0
  151. package/dist/transport/grpc/codec.d.ts +40 -0
  152. package/dist/transport/grpc/codec.d.ts.map +1 -0
  153. package/dist/transport/grpc/codec.js +231 -0
  154. package/dist/transport/grpc/codec.js.map +1 -0
  155. package/dist/transport/grpc/grpc-transport.d.ts +115 -0
  156. package/dist/transport/grpc/grpc-transport.d.ts.map +1 -0
  157. package/dist/transport/grpc/grpc-transport.js +577 -0
  158. package/dist/transport/grpc/grpc-transport.js.map +1 -0
  159. package/dist/transport/grpc/messages.d.ts +221 -0
  160. package/dist/transport/grpc/messages.d.ts.map +1 -0
  161. package/dist/transport/grpc/messages.js +56 -0
  162. package/dist/transport/grpc/messages.js.map +1 -0
  163. package/dist/transport/grpc/proto.d.ts +71 -0
  164. package/dist/transport/grpc/proto.d.ts.map +1 -0
  165. package/dist/transport/grpc/proto.js +67 -0
  166. package/dist/transport/grpc/proto.js.map +1 -0
  167. package/dist/transport/http.d.ts +62 -0
  168. package/dist/transport/http.d.ts.map +1 -0
  169. package/dist/transport/http.js +169 -0
  170. package/dist/transport/http.js.map +1 -0
  171. package/dist/transport/ndjson-row-source.d.ts +38 -0
  172. package/dist/transport/ndjson-row-source.d.ts.map +1 -0
  173. package/dist/transport/ndjson-row-source.js +197 -0
  174. package/dist/transport/ndjson-row-source.js.map +1 -0
  175. package/dist/transport/rest-decode.d.ts +33 -0
  176. package/dist/transport/rest-decode.d.ts.map +1 -0
  177. package/dist/transport/rest-decode.js +162 -0
  178. package/dist/transport/rest-decode.js.map +1 -0
  179. package/dist/transport/rest-prepared-cache.d.ts +50 -0
  180. package/dist/transport/rest-prepared-cache.d.ts.map +1 -0
  181. package/dist/transport/rest-prepared-cache.js +101 -0
  182. package/dist/transport/rest-prepared-cache.js.map +1 -0
  183. package/dist/transport/rest-transport.d.ts +88 -0
  184. package/dist/transport/rest-transport.d.ts.map +1 -0
  185. package/dist/transport/rest-transport.js +388 -0
  186. package/dist/transport/rest-transport.js.map +1 -0
  187. package/dist/transport/transport-pool.d.ts +40 -0
  188. package/dist/transport/transport-pool.d.ts.map +1 -0
  189. package/dist/transport/transport-pool.js +48 -0
  190. package/dist/transport/transport-pool.js.map +1 -0
  191. package/dist/transport/transport.d.ts +199 -0
  192. package/dist/transport/transport.d.ts.map +1 -0
  193. package/dist/transport/transport.js +11 -0
  194. package/dist/transport/transport.js.map +1 -0
  195. package/dist/values/decode.d.ts +39 -0
  196. package/dist/values/decode.d.ts.map +1 -0
  197. package/dist/values/decode.js +75 -0
  198. package/dist/values/decode.js.map +1 -0
  199. package/dist/values/encode.d.ts +45 -0
  200. package/dist/values/encode.d.ts.map +1 -0
  201. package/dist/values/encode.js +271 -0
  202. package/dist/values/encode.js.map +1 -0
  203. package/dist/values/ticks.d.ts +31 -0
  204. package/dist/values/ticks.d.ts.map +1 -0
  205. package/dist/values/ticks.js +52 -0
  206. package/dist/values/ticks.js.map +1 -0
  207. package/dist/values/typed.d.ts +67 -0
  208. package/dist/values/typed.d.ts.map +1 -0
  209. package/dist/values/typed.js +134 -0
  210. package/dist/values/typed.js.map +1 -0
  211. package/dist/values/uuid.d.ts +27 -0
  212. package/dist/values/uuid.d.ts.map +1 -0
  213. package/dist/values/uuid.js +76 -0
  214. package/dist/values/uuid.js.map +1 -0
  215. package/dist/vector.d.ts +26 -0
  216. package/dist/vector.d.ts.map +1 -0
  217. package/dist/vector.js +48 -0
  218. package/dist/vector.js.map +1 -0
  219. package/package.json +86 -0
  220. package/proto/camus_sql.proto +566 -0
@@ -0,0 +1,566 @@
1
+ syntax = "proto3";
2
+
3
+ option csharp_namespace = "CamusDB.Grpc";
4
+
5
+ // ─── Enums ────────────────────────────────────────────────────────────────────
6
+
7
+ // Mirrors CamusDB.Core.Catalogs.Models.ColumnType integer values exactly.
8
+ // Do not renumber or reuse values.
9
+ enum ColumnType {
10
+ COLUMN_TYPE_NULL = 0;
11
+ COLUMN_TYPE_ID = 1;
12
+ COLUMN_TYPE_INTEGER64 = 2;
13
+ COLUMN_TYPE_STRING = 3;
14
+ COLUMN_TYPE_BOOL = 4;
15
+ COLUMN_TYPE_FLOAT64 = 5;
16
+ COLUMN_TYPE_FLOAT32 = 6;
17
+ COLUMN_TYPE_BYTES = 7;
18
+ COLUMN_TYPE_DATE = 8;
19
+ COLUMN_TYPE_DATETIME = 9;
20
+ COLUMN_TYPE_ARRAY = 10;
21
+ COLUMN_TYPE_UUID = 11;
22
+ }
23
+
24
+ enum IsolationLevel {
25
+ ISOLATION_LEVEL_UNSPECIFIED = 0;
26
+ ISOLATION_LEVEL_READ_COMMITTED = 1;
27
+ ISOLATION_LEVEL_SERIALIZABLE = 2;
28
+ }
29
+
30
+ enum TransactionMode {
31
+ TRANSACTION_MODE_UNSPECIFIED = 0;
32
+ TRANSACTION_MODE_READ_WRITE = 1;
33
+ TRANSACTION_MODE_READ_ONLY = 2;
34
+ }
35
+
36
+ // Locking mode: mirrors the opt-in SET TRANSACTION LOCKING / REST "locking" field.
37
+ // Absent (UNSPECIFIED) means use the server default (Pessimistic).
38
+ enum LockingMode {
39
+ LOCKING_MODE_UNSPECIFIED = 0;
40
+ LOCKING_MODE_PESSIMISTIC = 1;
41
+ LOCKING_MODE_OPTIMISTIC = 2;
42
+ }
43
+
44
+ // Admission priority: which transaction the server starts first when the node is at its
45
+ // configured concurrency ceiling. Ordering only — never affects isolation, locking or commit.
46
+ //
47
+ // Deliberately offset by one from the server-side enum so zero means UNSPECIFIED. A client built
48
+ // before this field existed necessarily sends 0, and 0 must fall through to the server default
49
+ // (Normal), never to BACKGROUND — otherwise upgrading the server would silently demote every old
50
+ // client's transactions to the bottom of the queue.
51
+ enum TransactionPriority {
52
+ TRANSACTION_PRIORITY_UNSPECIFIED = 0;
53
+ TRANSACTION_PRIORITY_BACKGROUND = 1;
54
+ TRANSACTION_PRIORITY_LOW = 2;
55
+ TRANSACTION_PRIORITY_NORMAL = 3;
56
+ TRANSACTION_PRIORITY_HIGH = 4;
57
+ TRANSACTION_PRIORITY_CRITICAL = 5;
58
+ }
59
+
60
+ enum OrderDirection {
61
+ ORDER_ASCENDING = 0;
62
+ ORDER_DESCENDING = 1;
63
+ }
64
+
65
+ // Typed NULL placeholder — a single value so the oneof still distinguishes
66
+ // "null was explicitly sent" from "field absent".
67
+ enum NullValue {
68
+ NULL_VALUE_UNSET = 0;
69
+ }
70
+
71
+ // ─── Value model ──────────────────────────────────────────────────────────────
72
+
73
+ // Compact-raw wire encoding for every ColumnType. Date/DateTime as raw int64 ticks;
74
+ // Uuid as 16 big-endian bytes (high-half || low-half); Id in its own field distinct
75
+ // from string_value. An Array still carries its element type so an empty array
76
+ // round-trips its ColumnValue.ArrayElementType.
77
+ message Value {
78
+ oneof kind {
79
+ NullValue null_value = 1; // typed NULL
80
+ string id_value = 2; // ObjectId — 24 lowercase hex chars
81
+ int64 int64_value = 3;
82
+ string string_value = 4;
83
+ bool bool_value = 5;
84
+ double float64_value = 6;
85
+ float float32_value = 7;
86
+ bytes bytes_value = 8;
87
+ int64 date_value = 9; // raw DateTime.Ticks, UTC, midnight-truncated
88
+ int64 datetime_value = 10; // raw DateTime.Ticks, UTC
89
+ ArrayValue array_value = 11; // nested Values + element type
90
+ bytes uuid_value = 12; // 16 bytes, big-endian high||low
91
+ }
92
+ }
93
+
94
+ // element_type is carried so an empty array still round-trips its element type.
95
+ message ArrayValue {
96
+ ColumnType element_type = 1;
97
+ repeated Value items = 2;
98
+ }
99
+
100
+ // ─── Schema / row messages ────────────────────────────────────────────────────
101
+
102
+ message ColumnSchema {
103
+ string name = 1;
104
+ ColumnType type = 2;
105
+ }
106
+
107
+ // Ordered output column schema. Emitted once as the first message in every
108
+ // query stream, even for an empty result set.
109
+ message ResultSchema {
110
+ repeated ColumnSchema columns = 1;
111
+ }
112
+
113
+ // One positional row — values[i] aligns to ResultSchema.columns[i].
114
+ message ResultRow {
115
+ repeated Value values = 1;
116
+ }
117
+
118
+ // Hybrid Logical Clock instant. Mirrors Kommander.Time.HLCTimestamp's (L, C) pair as the
119
+ // response envelope surfaces it — the node dimension N is not part of the cache report.
120
+ message HlcTimestamp {
121
+ int64 l = 1;
122
+ uint32 c = 2;
123
+ }
124
+
125
+ // Cache resolution metadata for a "{cache=name}"-hinted SELECT, mirroring the REST response
126
+ // envelope field-for-field. It is emitted ONLY when the statement entered the cache path, so a
127
+ // client distinguishes "query was not hinted" (message absent) from "hinted and bypassed"
128
+ // (message present with status = "bypass" and a bypass_reason).
129
+ message CacheMetadata {
130
+ // "hit" | "miss" | "bypass" | "stale-revalidated" | "evicted-before-publish".
131
+ string status = 1;
132
+ // Why the cache was bypassed or the entry was not published (e.g. "in-flight-write",
133
+ // "oversized-result"). Empty when the status carries no bypass reason.
134
+ string bypass_reason = 2;
135
+ // Logical cache family name from the hint; always set when this message is emitted.
136
+ string name = 3;
137
+ // Instant at which a served entry was computed. Present only on a cache hit.
138
+ HlcTimestamp cached_at_hlc = 4;
139
+ // Approximate wall-clock age of a served entry. Present only on a cache hit.
140
+ optional int64 age_ms = 5;
141
+ }
142
+
143
+ // Whether routing advice asks the client to remember or to forget a destination.
144
+ enum RoutingDisposition {
145
+ ROUTING_DISPOSITION_UNSPECIFIED = 0;
146
+ // Remember the advertised node for future executions of this statement context.
147
+ ROUTING_DISPOSITION_PREFER = 1;
148
+ // Forget any previously learned destination for this statement context.
149
+ ROUTING_DISPOSITION_CLEAR = 2;
150
+ }
151
+
152
+ // How broadly a learned destination may be reused. A client MUST NOT treat an
153
+ // unrecognized value as parameter-independent; it must ignore the advice instead.
154
+ enum RoutingReuseScope {
155
+ ROUTING_REUSE_SCOPE_UNSPECIFIED = 0;
156
+ // The destination holds for future executions of this exact statement and binding
157
+ // context, across different parameter values.
158
+ ROUTING_REUSE_SCOPE_STATEMENT_PARAMETERS_INDEPENDENT = 1;
159
+ }
160
+
161
+ // Advisory routing metadata attached to a successful statement response, emitted only when the
162
+ // request negotiated it (SqlRequest.routing_accept_version = 1). It is a performance hint, never
163
+ // an instruction: the operation that carried it already executed normally, and a client that
164
+ // ignores it loses nothing but a network hop. The server emits it only after the statement's
165
+ // normal authorization checks, and it never carries SQL literals, row values, encoded keys,
166
+ // credentials, or a cluster map.
167
+ message RoutingAdvice {
168
+ // Metadata contract version; today always 1. A client MUST ignore versions it does not know.
169
+ int32 version = 1;
170
+ RoutingDisposition disposition = 2;
171
+ // Opaque node identity to prefer. The client maps it to a CONFIGURED endpoint address; it is
172
+ // never an address to dial directly, and an identity absent from the client's map is unusable
173
+ // advice, not an error.
174
+ string preferred_node_id = 3;
175
+ RoutingReuseScope reuse_scope = 4;
176
+ // Opaque change detector over the statement's resolved physical dependencies. It changes when
177
+ // the dependency set changes (schema change, TRUNCATE, materialized-view refresh, database
178
+ // recreation). Not sortable, not an authority, not authentication.
179
+ string dependency_token = 5;
180
+ // Maximum reuse period, measured by the client with a monotonic clock from receipt. Bounded
181
+ // further by client policy.
182
+ int32 max_age_ms = 6;
183
+ // How the server knows: "placementHint" = this node's local placement belief, not proof of
184
+ // which node executed the underlying storage operations.
185
+ string provenance = 7;
186
+ // Why this disposition: "singleTableHash", "ineligible", "placementUnknown", "cacheAffinity".
187
+ string reason = 8;
188
+ }
189
+
190
+ // Streamed query response: exactly one Schema first, then zero or more Rows, then — only for a
191
+ // cache-hinted statement — one trailing CacheMetadata. The cache verdict is known only after the
192
+ // cursor is fully drained, so it can never precede the rows. A request that negotiated routing
193
+ // metadata may additionally receive one trailing RoutingAdvice after the rows (and after any
194
+ // CacheMetadata); a client that did not negotiate never sees it.
195
+ message QueryStreamMessage {
196
+ oneof payload {
197
+ ResultSchema schema = 1;
198
+ ResultRow row = 2;
199
+ CacheMetadata cache_metadata = 3;
200
+ RoutingAdvice routing_advice = 4;
201
+ }
202
+ }
203
+
204
+ // ─── Batched execution (duplex) ────────────────────────────────────────────────
205
+ // Pipelines many ExecuteQuery / ExecuteNonQuery statements over ONE bidirectional
206
+ // stream so an EF Core provider avoids a unary round-trip per statement. Every message
207
+ // carries a client-monotonic request_id; responses for different ids interleave and the
208
+ // client demultiplexes by id (mirrors Kahuna's BatchClientKeyValueRequests). Ops sharing
209
+ // a txn_handle are executed in arrival order; autocommit ops run concurrently. Per-op
210
+ // metadata (causal token, error) is carried IN-BAND because gRPC trailers are per-call
211
+ // and one BatchExecute call carries many ops.
212
+
213
+ enum BatchStatementKind {
214
+ BATCH_STATEMENT_KIND_UNSPECIFIED = 0;
215
+ BATCH_STATEMENT_KIND_QUERY = 1; // route to ExecuteQuery — streams schema + rows
216
+ BATCH_STATEMENT_KIND_NON_QUERY = 2; // route to ExecuteNonQuery — single reply
217
+ // Transaction lifecycle folded onto the same stream so a whole unit of work (begin, statements,
218
+ // commit) rides one duplex call and many concurrent transactions keep the stream busy. START reuses
219
+ // SqlRequest.database + isolation/mode/locking (sql ignored) and its reply carries the server-minted
220
+ // handle; COMMIT/ROLLBACK reference SqlRequest.txn_handle.
221
+ BATCH_STATEMENT_KIND_START = 3; // begin a transaction — reply carries the TxnHandle
222
+ BATCH_STATEMENT_KIND_COMMIT = 4; // commit request.txn_handle — reply carries the causal token
223
+ BATCH_STATEMENT_KIND_ROLLBACK = 5; // roll back request.txn_handle
224
+ // Prepared statements, scoped to THIS stream. PREPARE registers SqlRequest.database +
225
+ // SqlRequest.sql and replies with an id plus the parameter names in binding order; later QUERY /
226
+ // NON_QUERY ops execute by that id and send values positionally, so neither the SQL nor the
227
+ // parameter names travel again. CLOSE frees one id (SqlRequest.statement_id).
228
+ BATCH_STATEMENT_KIND_PREPARE = 6;
229
+ BATCH_STATEMENT_KIND_CLOSE = 7;
230
+ }
231
+
232
+ // PREPARE terminator. The client MUST await this reply before sending any op that references the
233
+ // id — exactly the contract START has — so an execution can never race its own registration.
234
+ message PrepareReply {
235
+ int32 statement_id = 1;
236
+ // Distinct placeholder names in binding order, verbatim INCLUDING the leading '@':
237
+ // positional_parameters[i] binds to parameter_names[i] on every execution of this statement.
238
+ repeated string parameter_names = 2;
239
+ }
240
+
241
+ // CLOSE terminator. Closing an unknown id succeeds — the requested end state already holds.
242
+ message CloseReply {}
243
+
244
+ message BatchExecuteRequest {
245
+ int32 request_id = 1; // echoed on every response for this op
246
+ BatchStatementKind kind = 2;
247
+ SqlRequest request = 3; // same shape as the unary path
248
+ }
249
+
250
+ // In-band domain error for one batched op (mirrors the error code/message the unary calls put in
251
+ // gRPC trailers, which are unavailable per-op on a shared call). code is the CADBxxxx string.
252
+ message BatchError {
253
+ string code = 1;
254
+ string message = 2;
255
+ }
256
+
257
+ // Terminates a QUERY op's result set on the shared stream and carries its trailing metadata.
258
+ message QueryComplete {
259
+ int64 total = 1;
260
+ int64 causal_token_l = 2;
261
+ int64 causal_token_c = 3;
262
+ int32 causal_token_n = 4;
263
+ // Present only for a cache-hinted statement — the batch terminator carries the verdict because
264
+ // it is known only once the cursor has been drained.
265
+ CacheMetadata cache_metadata = 5;
266
+ // Present only when the request negotiated routing metadata (routing_accept_version = 1) and
267
+ // the statement produced advice. Advisory — see RoutingAdvice.
268
+ RoutingAdvice routing = 6;
269
+ }
270
+
271
+ message BatchExecuteResponse {
272
+ int32 request_id = 1;
273
+ oneof payload {
274
+ ResultSchema schema = 2; // QUERY: one, first for this request_id (even if empty)
275
+ ResultRow row = 3; // QUERY: zero or more
276
+ QueryComplete query_complete = 4; // QUERY: terminator
277
+ NonQueryReply non_query = 5; // NON_QUERY: single terminal reply
278
+ BatchError error = 6; // terminal error for this request_id
279
+ TxnHandle start_reply = 7; // START: terminator — the server-minted handle
280
+ CommitReply commit_reply = 8; // COMMIT: terminator — causal token
281
+ RollbackReply rollback_reply = 9; // ROLLBACK: terminator
282
+ PrepareReply prepare_reply = 10; // PREPARE: terminator — id + parameter names
283
+ CloseReply close_reply = 11; // CLOSE: terminator
284
+ }
285
+ }
286
+
287
+ // ─── Transaction handle ───────────────────────────────────────────────────────
288
+
289
+ // Identifies an open explicit transaction. Mirrors the (TxnIdPT, TxnIdCounter)
290
+ // pair that the HTTP session model uses.
291
+ message TxnHandle {
292
+ int64 txn_id_pt = 1;
293
+ uint32 txn_id_counter = 2;
294
+ // Optional causal token from the previous operation in this session. The three
295
+ // components mirror HLCTimestamp (N, L, C) exactly — N is the node-id dimension and
296
+ // is load-bearing (it participates in HLCTimestamp equality and is the CompareTo
297
+ // tie-breaker), so it must travel with L/C or the token is a lossy copy.
298
+ int32 causal_token_n = 5;
299
+ int64 causal_token_l = 3;
300
+ int64 causal_token_c = 4;
301
+ }
302
+
303
+ // ─── Filter / ordering ───────────────────────────────────────────────────────
304
+
305
+ // op stays a string (mirrors QueryFilter.Op in the engine — "=", ">", "LIKE", …)
306
+ // so the proto surface never drifts from what CommandExecutor accepts.
307
+ message QueryFilter {
308
+ string column_name = 1;
309
+ string op = 2;
310
+ Value value = 3;
311
+ }
312
+
313
+ message OrderBy {
314
+ string column_name = 1;
315
+ OrderDirection direction = 2;
316
+ }
317
+
318
+ // ─── CamusSql service ─────────────────────────────────────────────────────────
319
+
320
+ // SQL request shared by ExecuteQuery, ExecuteNonQuery, and ExecuteDdl.
321
+ message SqlRequest {
322
+ string database = 1;
323
+ string sql = 2;
324
+
325
+ map<string, Value> parameters = 3;
326
+
327
+ // Optional explicit transaction to resume. Absent = autocommit.
328
+ TxnHandle txn_handle = 4;
329
+
330
+ // Optional: override isolation, mode, and locking for the autocommit txn begun
331
+ // by this request. Ignored when txn_handle resumes an existing transaction.
332
+ IsolationLevel isolation_level = 5;
333
+ TransactionMode transaction_mode = 6;
334
+ LockingMode locking = 7;
335
+
336
+ // Optional causal token from a prior operation in the same session.
337
+ // (N, L, C) mirror HLCTimestamp — see TxnHandle for why N must travel with L/C.
338
+ int64 causal_token_l = 8;
339
+ int64 causal_token_c = 9;
340
+ int32 causal_token_n = 10;
341
+
342
+ // Prepared execution: when > 0, `sql`, `database` and `parameters` MUST be absent — the statement
343
+ // id already names all three, and sending both is an error rather than a precedence rule.
344
+ // 0 = classic inline request, unchanged semantics. Valid only on BatchExecute ops (the id is
345
+ // scoped to a stream); the unary RPCs reject it.
346
+ int32 statement_id = 11;
347
+
348
+ // Ordinal parameter values for a prepared execution; index i binds to parameter_names[i] from the
349
+ // PREPARE reply. The count must equal the declared parameter count exactly.
350
+ repeated Value positional_parameters = 12;
351
+
352
+ // Optional admission priority for the transaction begun by this request. Ignored when
353
+ // txn_handle resumes an existing transaction — priority is consumed when the coordinator
354
+ // session opens, so a resumed transaction has already spent it.
355
+ TransactionPriority priority = 13;
356
+
357
+ // Highest RoutingAdvice version the client accepts on this operation's response. 0 (the value
358
+ // every pre-routing client necessarily sends) means "do not emit routing metadata", so old
359
+ // clients keep their exact response shape. Today the only accepted value is 1.
360
+ int32 routing_accept_version = 14;
361
+ }
362
+
363
+ message NonQueryReply {
364
+ int32 affected_rows = 1;
365
+ int64 causal_token_l = 2;
366
+ int64 causal_token_c = 3;
367
+ int32 causal_token_n = 4;
368
+
369
+ // Set when the statement succeeded but the caller should look twice — today, a time-travel copy
370
+ // that read no rows, which may mean the requested history had already been reclaimed. Empty
371
+ // otherwise. Carried here because a client cannot see the server's log.
372
+ string warning = 5;
373
+
374
+ // Present only when the request negotiated routing metadata (routing_accept_version = 1) and
375
+ // the statement produced advice. Advisory — see RoutingAdvice.
376
+ RoutingAdvice routing = 6;
377
+ }
378
+
379
+ message DdlReply {
380
+ int64 causal_token_l = 1;
381
+ int64 causal_token_c = 2;
382
+ int32 causal_token_n = 3;
383
+
384
+ // Rows written by a DDL statement that also loads data — today only CREATE TABLE ... AS SELECT.
385
+ // Zero for every other DDL statement, which writes no rows.
386
+ int32 affected_rows = 4;
387
+
388
+ // See NonQueryReply.warning.
389
+ string warning = 5;
390
+ }
391
+
392
+ message StartTxnRequest {
393
+ string database = 1;
394
+ IsolationLevel isolation_level = 2;
395
+ TransactionMode transaction_mode = 3;
396
+ LockingMode locking = 4;
397
+ TransactionPriority priority = 5;
398
+ }
399
+
400
+ message CommitReply {
401
+ int64 causal_token_l = 1;
402
+ int64 causal_token_c = 2;
403
+ int32 causal_token_n = 3;
404
+ }
405
+
406
+ message RollbackReply {}
407
+
408
+ message PingRequest {}
409
+
410
+ message PingReply {
411
+ string message = 1;
412
+ }
413
+
414
+ // SQL-centric service: mirrors /execute-sql-query, /execute-sql-non-query,
415
+ // /execute-sql-ddl, and the transaction lifecycle endpoints.
416
+ service CamusSql {
417
+ // Server-streaming: first message is the output-column schema (even for an
418
+ // empty result), followed by one message per row from the cursor.
419
+ rpc ExecuteQuery (SqlRequest) returns (stream QueryStreamMessage);
420
+ rpc ExecuteNonQuery (SqlRequest) returns (NonQueryReply);
421
+ rpc ExecuteDdl (SqlRequest) returns (DdlReply);
422
+ // Duplex batching of ExecuteQuery / ExecuteNonQuery over one stream. Responses are correlated by
423
+ // request_id and interleave/arrive out of order across ops; same-txn ops run in arrival order.
424
+ rpc BatchExecute (stream BatchExecuteRequest) returns (stream BatchExecuteResponse);
425
+ rpc StartTransaction (StartTxnRequest) returns (TxnHandle);
426
+ rpc CommitTransaction (TxnHandle) returns (CommitReply);
427
+ rpc RollbackTransaction(TxnHandle) returns (RollbackReply);
428
+ rpc Ping (PingRequest) returns (PingReply);
429
+ }
430
+
431
+ // ─── CamusAuth service ────────────────────────────────────────────────────────
432
+ // Credential exchange, mirroring the REST /login and /logout routes. Deliberately a service of its
433
+ // own rather than two more RPCs on CamusSql: these are the ONLY calls that must be reachable without
434
+ // a bearer token (a client has none until Login returns one), so keeping them separate makes the
435
+ // unauthenticated surface explicit instead of hiding an exemption inside the data-plane service.
436
+
437
+ message LoginRequest {
438
+ string user = 1;
439
+ string password = 2;
440
+ }
441
+
442
+ message LoginReply {
443
+ // Opaque bearer token; present it as "Bearer <token>" in the `authorization` call metadata.
444
+ string token = 1;
445
+ // Absolute deadline after which the token is rejected — Unix epoch milliseconds, UTC.
446
+ int64 expires_at_unix_ms = 2;
447
+ // Whole seconds until that deadline as the SERVER measured it when replying. Redundant with the
448
+ // absolute value on purpose: a client whose clock disagrees can renew on a monotonic timer.
449
+ int64 expires_in_seconds = 3;
450
+ }
451
+
452
+ // The token is taken from the `authorization` metadata, exactly as on every other authenticated call,
453
+ // so it is never duplicated in the message body.
454
+ message LogoutRequest {}
455
+
456
+ message LogoutReply {}
457
+
458
+ service CamusAuth {
459
+ // Exchanges a password for a short-lived bearer token. Refused over a plaintext connection when
460
+ // authentication requires TLS — a password must never travel in the clear.
461
+ rpc Login (LoginRequest) returns (LoginReply);
462
+ // Revokes the token presented in the `authorization` metadata. Idempotent.
463
+ rpc Logout (LogoutRequest) returns (LogoutReply);
464
+ }
465
+
466
+ // ─── CamusRows service ────────────────────────────────────────────────────────
467
+
468
+ message InsertRowRequest {
469
+ string database = 1;
470
+ string table = 2;
471
+
472
+ map<string, Value> values = 3;
473
+
474
+ TxnHandle txn_handle = 4;
475
+ int64 causal_token_l = 5;
476
+ int64 causal_token_c = 6;
477
+ LockingMode locking = 7;
478
+ int32 causal_token_n = 8;
479
+ TransactionPriority priority = 9;
480
+ }
481
+
482
+ message RowQueryRequest {
483
+ string database = 1;
484
+ string table = 2;
485
+ string index_name = 3; // optional; empty = primary scan
486
+
487
+ repeated QueryFilter filters = 4;
488
+ repeated OrderBy order_by = 5;
489
+
490
+ TxnHandle txn_handle = 6;
491
+ int64 causal_token_l = 7;
492
+ int64 causal_token_c = 8;
493
+ LockingMode locking = 9;
494
+ int32 causal_token_n = 10;
495
+ TransactionPriority priority = 11;
496
+ }
497
+
498
+ message RowByIdRequest {
499
+ string database = 1;
500
+ string table = 2;
501
+ string id = 3;
502
+
503
+ TxnHandle txn_handle = 4;
504
+ int64 causal_token_l = 5;
505
+ int64 causal_token_c = 6;
506
+ LockingMode locking = 7;
507
+ int32 causal_token_n = 8;
508
+ TransactionPriority priority = 9;
509
+ }
510
+
511
+ message UpdateRowsRequest {
512
+ string database = 1;
513
+ string table = 2;
514
+
515
+ map<string, Value> values = 3;
516
+ repeated QueryFilter filters = 4;
517
+
518
+ TxnHandle txn_handle = 5;
519
+ int64 causal_token_l = 6;
520
+ int64 causal_token_c = 7;
521
+ LockingMode locking = 8;
522
+ int32 causal_token_n = 9;
523
+ TransactionPriority priority = 10;
524
+ }
525
+
526
+ message UpdateByIdRequest {
527
+ string database = 1;
528
+ string table = 2;
529
+ string id = 3;
530
+
531
+ map<string, Value> values = 4;
532
+
533
+ TxnHandle txn_handle = 5;
534
+ int64 causal_token_l = 6;
535
+ int64 causal_token_c = 7;
536
+ LockingMode locking = 8;
537
+ int32 causal_token_n = 9;
538
+ TransactionPriority priority = 10;
539
+ }
540
+
541
+ message DeleteRowsRequest {
542
+ string database = 1;
543
+ string table = 2;
544
+
545
+ repeated QueryFilter filters = 3;
546
+
547
+ TxnHandle txn_handle = 4;
548
+ int64 causal_token_l = 5;
549
+ int64 causal_token_c = 6;
550
+ LockingMode locking = 7;
551
+ int32 causal_token_n = 8;
552
+ TransactionPriority priority = 9;
553
+ }
554
+
555
+ // Typed row-level service: mirrors InsertController / QueryController /
556
+ // UpdateController / DeleteController for hot-path CRUD without composing SQL.
557
+ service CamusRows {
558
+ rpc InsertRow (InsertRowRequest) returns (NonQueryReply);
559
+ // Server-streaming, schema-first — same QueryStreamMessage shape as CamusSql.ExecuteQuery.
560
+ rpc Query (RowQueryRequest) returns (stream QueryStreamMessage);
561
+ rpc QueryById (RowByIdRequest) returns (stream QueryStreamMessage);
562
+ rpc UpdateRows (UpdateRowsRequest) returns (NonQueryReply);
563
+ rpc UpdateById (UpdateByIdRequest) returns (NonQueryReply);
564
+ rpc DeleteRows (DeleteRowsRequest) returns (NonQueryReply);
565
+ rpc DeleteById (RowByIdRequest) returns (NonQueryReply);
566
+ }