FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
stategraph/code/src/pgsql_codec/pgsql_codec.ml at main · stategraph/stategraph · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
stategraph
/
stategraph
Public
Notifications
You must be signed in to change notification settings
Fork
73
Star
1.3k
Code
Issues
107
Pull requests
0
Discussions
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Discussions
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
stategraph
/
code
/
src
/
pgsql_codec
/
pgsql_codec.ml
Copy path
More file actions
More file actions
Latest commit
History
History
History
603 lines (559 loc) · 18.6 KB
Breadcrumbs
stategraph
/
code
/
src
/
pgsql_codec
/
pgsql_codec.ml
Copy path
File metadata and controls
603 lines (559 loc) · 18.6 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
module
Reader
:
sig
type
err
=
[
`Unknown_type
of
char
|
`Length
|
`Needed_bytes
of
int
|
`Invalid_frame
]
type
'a t
val
run
:
buf
:
Bytes
.
t
->
pos
:
int
->
len
:
int
->
'a
t
-> (
'a
*
int
,
err
*
int
)
result
val (
>>
=
) : 'a t -> ('a -> 'b t) -> 'b t
val
return
:
'a
->
'a
t
val
fail
:
err
->
'a
t
val
int32
:
int32
t
val
bytes
:
int
->
string
t
val
string
:
string
t
val
string_list
:
unit
->
string
list
t
val
int8
:
int
t
val
int16
:
int
t
val
repeat
:
int
->
'a
t
->
'a
list
t
val
consume
:
int
->
'a
t
->
'a
list
t
end
=
struct
module
State
=
struct
type
t
= {
buf
:
Bytes
.t
;
pos
:
int
;
stop
:
int
;
}
end
type
err
=
[
`Unknown_type
of
char
|
`Length
|
`Needed_bytes
of
int
|
`Invalid_frame
]
type
'a t
=
State
.t
-> (
'a
,
err
)
result
*
State
.t
let
( >>= )
t
f
st
=
match
t st
with
|
Ok
v
,
st
-> f v st
|
(Error
_
,
_
)
as
r
-> r
let
return
v
st
=
(
Ok
v, st)
let
fail
err
st
=
(
Error
err, st)
let
run
~
buf
~
pos
~
len
t
=
let
st
=
State.
{ buf; pos; stop
=
pos
+
len }
in
assert
(st.
State.
stop
<
=
Bytes.
length buf);
match
t st
with
|
Error
(
_
as
err
),
st
->
Error
(err, st.
State.
pos)
|
Ok
v
,
st
->
Ok
(v, st.
State.
pos)
let
int32
st
=
if
st.
State.
pos
+
4
<
=
st.
State.
stop
then
let
n
=
EndianBytes.BigEndian.
get_int32 st.
State.
buf st.
State.
pos
in
(
Ok
n, { st
with
State.
pos
=
st.
State.
pos
+
4
})
else
(
Error
`Length
, st)
let
bytes
n
st
=
assert
(n
>
=
0
);
if
st.
State.
pos
+
n
<
=
st.
State.
stop
then
let
s
=
Bytes.
sub_string st.
State.
buf st.
State.
pos n
in
(
Ok
s, { st
with
State.
pos
=
st.
State.
pos
+
n })
else
(
Error
(
`Needed_bytes
(n
-
(st.
State.
stop
-
st.
State.
pos))), st)
let
string
st
=
match
Bytes.
index_from_opt st.
State.
buf st.
State.
pos
'\000'
with
|
Some
idx
when
idx
<
st.
State.
stop ->
let
s
=
Bytes.
sub_string st.
State.
buf st.
State.
pos (idx
-
st.
State.
pos)
in
(*
+1 to consume the end null byte
*)
(
Ok
s, { st
with
State.
pos
=
st.
State.
pos
+
(idx
-
st.
State.
pos)
+
1
})
|
_
-> (
Error
`Length
, st)
let
rec
string_list
()
=
string
>>
=
function
|
""
-> return
[]
|
auth_mechanism
-> string_list
()
>>
=
fun
rest
-> return (auth_mechanism :: rest)
let
int8
st
=
if
st.
State.
pos
+
1
<
=
st.
State.
stop
then
let
n
=
Bytes.
get_uint8 st.
State.
buf st.
State.
pos
in
(
Ok
n, { st
with
State.
pos
=
st.
State.
pos
+
1
})
else
(
Error
`Length
, st)
let
int16
st
=
if
st.
State.
pos
+
2
<
=
st.
State.
stop
then
let
n
=
EndianBytes.BigEndian.
get_int16 st.
State.
buf st.
State.
pos
in
(
Ok
n, { st
with
State.
pos
=
st.
State.
pos
+
2
})
else
(
Error
`Length
, st)
let
rec
repeat
n
t
st
=
if
n
>
0
then
match
t st
with
|
Ok
v
,
st
-> (
match
repeat (n
-
1
) t st
with
|
Ok
vs
,
st
-> (
Ok
(v :: vs), st)
|
(Error
_
as
err
),
st
-> (err, st))
|
(Error
_
as
err
),
st
-> (err, st)
else
(
Ok
[]
, st)
let
rec
consume
len
t
st
=
if
len
>
0
then
let
pos
=
st.
State.
pos
in
match
t st
with
|
Ok
v
,
st
-> (
let
consumed
=
st.
State.
pos
-
pos
in
let
len
=
len
-
consumed
in
match
consume len t st
with
|
Ok
vs
,
st
-> (
Ok
(v :: vs), st)
|
(Error
_
as
err
),
st
-> (err, st))
|
(Error
_
as
err
),
st
-> (err, st)
else
(
Ok
[]
, st)
end
module
Writer
:
sig
type
t
val
run
:
Buffer
.t
->
t
->
unit
val
msg_code
:
char
->
t
val
int32
:
int32
->
t
val
int16
:
int
->
t
val
bytes
:
string
->
t
val
string
:
string
->
t
val
chr
:
char
->
t
val
iter
: (
'a
->
t
) ->
'a
list
->
t
val (
>>
=
) : t -> (
unit
-> t) -> t
end
=
struct
type
t
=
Buffer
.t
*
Buffer
.t
->
unit
let
msg_code
ch
(
b
,
_
)
=
Buffer.
add_char b ch
let
int32
n
(
_
,
buf
)
=
let
b
=
Bytes.
create
4
in
EndianBytes.BigEndian.
set_int32 b
0
n;
Buffer.
add_bytes buf b
let
int16
n
(
_
,
buf
)
=
let
b
=
Bytes.
create
2
in
EndianBytes.BigEndian.
set_int16 b
0
n;
Buffer.
add_bytes buf b
let
bytes
s
(
_
,
buf
)
=
Buffer.
add_string buf s
let
string
s
(
_
,
buf
)
=
Buffer.
add_string buf s;
Buffer.
add_char buf
'\000'
let
chr
ch
(
_
,
buf
)
=
Buffer.
add_char buf ch
let
iter
f
xs
bs
=
List.
iter (
fun
x
-> f x bs) xs
let
run
prepend_buf
t
=
let
buf
=
Buffer.
create
1024
in
t (prepend_buf, buf);
let
len
=
4
+
Buffer.
length buf
in
int32
(
Int32.
of_int len) (prepend_buf, prepend_buf);
Buffer.
add_buffer prepend_buf buf
let
( >>= )
t
f
buf
=
let
r
=
t buf
in
f r buf
end
module
Frame
=
struct
module
Backend
=
struct
type
row
= {
name
:
string
;
table_id
:
int32
;
column_attr
:
int
;
data_type_id
:
int32
;
data_type_size
:
int
;
data_type_mod
:
int32
;
format_code
:
int
;
}
[
@@
deriving
show
,
eq
]
type
t
=
|
AuthenticationOk
|
AuthenticationKerberosV5
|
AuthenticationCleartextPassword
|
AuthenticationMD5Password
of
{
salt
:
string
}
|
AuthenticationSCMCredential
|
AuthenticationGSS
|
AuthenticationSSPI
|
AuthenticationGSSContinue
of
{
data
:
string
}
|
AuthenticationSASL
of
{
auth_mechanisms
:
string
list
}
|
AuthenticationSASLContinue
of
{
data
:
string
}
|
AuthenticationSASLFinal
of
{
data
:
string
}
|
BackendKeyData
of
{
pid
:
int32
;
secret_key
:
int32
;
}
|
BindComplete
|
CloseComplete
|
CommandComplete
of
{
tag
:
string
}
|
CopyData
of
{
data
:
string
}
|
CopyDone
|
CopyInResponse
of
{
format
:
int
;
column_formats
:
int
list
;
}
|
CopyOutResponse
of
{
format
:
int
;
column_formats
:
int
list
;
}
|
CopyBothResponse
of
{
format
:
int
;
column_formats
:
int
list
;
}
|
DataRow
of
{
data
:
string
option
list
}
|
EmptyQueryResponse
|
ErrorResponse
of
{
msgs
: (
char
*
string
)
list
}
|
FunctionCallResponse
of
{
result
:
string
option
}
|
NegotiateProtocolVersion
of
{
minor_version
:
int32
;
unrecognized_options
:
string
list
;
}
|
NoData
|
NoticeResponse
of
{
msgs
: (
char
*
string
)
list
}
|
NotificationResponse
of
{
pid
:
int32
;
channel
:
string
;
payload
:
string
;
}
|
ParameterDescription
of
{
object_ids
:
int32
list
}
|
ParameterStatus
of
{
name
:
string
;
value
:
string
;
}
|
ParseComplete
|
PortalSuspended
|
ReadyForQuery
of
{
status
:
char
}
|
RowDescription
of
{
rows
:
row
list
}
[
@@
deriving
show
,
eq
]
end
module
Frontend
=
struct
type
t
=
|
Bind
of
{
portal
:
string
;
stmt
:
string
;
format_codes
:
bool
list
;
values
:
string
option
list
;
result_format_codes
:
bool
list
;
}
|
CancelRequest
of
{
pid
:
int32
;
secret_key
:
int32
;
}
|
Close
of
{
typ
:
char
;
name
:
string
;
}
|
CopyData
of
{
data
:
string
}
|
CopyDone
|
CopyFail
of
{
message
:
string
}
|
Describe
of
{
typ
:
char
;
name
:
string
;
}
|
Execute
of
{
portal
:
string
;
max_rows
:
int32
;
}
|
Flush
|
FunctionCall
(*
TODO
*)
|
GSSResponse
of
{
data
:
string
}
|
Parse
of
{
stmt
:
string
;
query
:
string
;
data_types
:
int32
list
;
}
|
PasswordMessage
of
{
password
:
string
}
|
Query
of
{
query
:
string
}
|
SASLInitialResponse
of
{
auth_mechanism
:
string
;
data
:
string
;
}
|
SASLResponse
of
{
data
:
string
}
|
SSLRequest
|
StartupMessage
of
{
msgs
: (
string
*
string
)
list
}
|
Sync
|
Terminate
[
@@
deriving
show
,
eq
]
end
end
module
Decode
=
struct
type
err
=
[
`Unknown_type
of
char
|
`Invalid_frame
]
[
@@
deriving
show
,
eq
]
type
t
= {
buf
:
Buffer
.t
;
mutable
needed_bytes
:
int
;
}
let
create
()
=
{ buf
=
Buffer.
create
4096
; needed_bytes
=
-
1
}
let
dispatch_backend_msg
len
=
let
open
Reader
in
let
open
Frame.Backend
in
function
|
'R'
-> (
int32
>>
=
fun
n
->
match
Int32.
to_int n
with
|
0
-> return
AuthenticationOk
|
2
-> return
AuthenticationKerberosV5
|
3
-> return
AuthenticationCleartextPassword
|
5
-> bytes
4
>>
=
fun
salt
-> return (
AuthenticationMD5Password
{ salt })
|
6
-> return
AuthenticationSCMCredential
|
7
-> return
AuthenticationGSS
|
9
-> return
AuthenticationSSPI
|
8
-> bytes (len
-
4
)
>>
=
fun
data
-> return (
AuthenticationGSSContinue
{ data })
|
10
->
string_list
()
>>
=
fun
auth_mechanisms
-> return (
AuthenticationSASL
{ auth_mechanisms })
|
11
-> bytes (len
-
4
)
>>
=
fun
data
-> return (
AuthenticationSASLContinue
{ data })
|
12
-> bytes (len
-
4
)
>>
=
fun
data
-> return (
AuthenticationSASLFinal
{ data })
|
_
-> fail
`Invalid_frame
)
|
'K'
->
int32
>>
=
fun
pid
->
int32
>>
=
fun
secret_key
-> return (
BackendKeyData
{ pid; secret_key })
|
'2'
-> return
BindComplete
|
'3'
-> return
CloseComplete
|
'C'
->
string
>>
=
fun
tag
-> return (
CommandComplete
{ tag })
|
'G'
->
int8
>>
=
fun
format
->
int16
>>
=
fun
num_columns
->
repeat num_columns int16
>>
=
fun
column_formats
-> return (
CopyInResponse
{ format; column_formats })
|
'H'
->
int8
>>
=
fun
format
->
int16
>>
=
fun
num_columns
->
repeat num_columns int16
>>
=
fun
column_formats
-> return (
CopyOutResponse
{ format; column_formats })
|
'W'
->
int8
>>
=
fun
format
->
int16
>>
=
fun
num_columns
->
repeat num_columns int16
>>
=
fun
column_formats
-> return (
CopyBothResponse
{ format; column_formats })
|
'd'
-> bytes len
>>
=
fun
data
-> return (
CopyData
{ data })
|
'c'
-> return
CopyDone
|
'D'
->
int16
>>
=
fun
columns
->
assert
(columns
>
0
);
repeat
columns
(
int32
>>
=
fun
n
->
match
Int32.
to_int n
with
|
-
1
-> return
None
|
n
-> bytes n
>>
=
fun
s
-> return (
Some
s))
>>
=
fun
data
-> return (
DataRow
{ data })
|
'I'
-> return
EmptyQueryResponse
|
'E'
->
consume (len
-
4
) (bytes
1
>>
=
fun
code
->
string
>>
=
fun
msg
-> return (code.[
0
], msg))
>>
=
fun
msgs
->
bytes
1
>>
=
fun
s
->
assert
(s.[
0
]
=
'\000'
);
return (
ErrorResponse
{ msgs })
|
'V'
->
int32
>>
=
fun
n
->
(
match
Int32.
to_int n
with
|
-
1
-> return
None
|
n
-> bytes n
>>
=
fun
s
-> return (
Some
s))
>>
=
fun
result
-> return (
FunctionCallResponse
{ result })
|
'v'
->
int32
>>
=
fun
minor_version
->
int32
>>
=
fun
n
->
repeat (
Int32.
to_int n)
string
>>
=
fun
unrecognized_options
->
return (
NegotiateProtocolVersion
{ minor_version; unrecognized_options })
|
'n'
-> return
NoData
|
'N'
->
consume (len
-
4
) (bytes
1
>>
=
fun
code
->
string
>>
=
fun
msg
-> return (code.[
0
], msg))
>>
=
fun
msgs
->
bytes
1
>>
=
fun
s
->
assert
(s.[
0
]
=
'\000'
);
return (
NoticeResponse
{ msgs })
|
'A'
->
int32
>>
=
fun
pid
->
string
>>
=
fun
channel
->
string
>>
=
fun
payload
-> return (
NotificationResponse
{ pid; channel; payload })
|
't'
->
int16
>>
=
fun
n
->
repeat n
int32
>>
=
fun
object_ids
-> return (
ParameterDescription
{ object_ids })
|
'S'
->
string
>>
=
fun
name
->
string
>>
=
fun
value
-> return (
ParameterStatus
{ name; value })
|
'1'
-> return
ParseComplete
|
's'
-> return
PortalSuspended
|
'Z'
-> bytes
1
>>
=
fun
status
-> return (
ReadyForQuery
{ status
=
status.[
0
] })
|
'T'
->
int16
>>
=
fun
num_fields
->
repeat
num_fields
(
string
>>
=
fun
name
->
int32
>>
=
fun
table_id
->
int16
>>
=
fun
column_attr
->
int32
>>
=
fun
data_type_id
->
int16
>>
=
fun
data_type_size
->
int32
>>
=
fun
data_type_mod
->
int16
>>
=
fun
format_code
->
return
{
name;
table_id;
column_attr;
data_type_id;
data_type_size;
data_type_mod;
format_code;
})
>>
=
fun
rows
-> return (
RowDescription
{ rows })
|
t
-> fail (
`Unknown_type
t)
let
rec
backend_msg
'
pos
buf
len
=
assert
(pos
>
=
0
);
assert
(len
>
=
0
);
assert
(len
<
=
Bytes.
length buf);
let
res
=
Reader.
run
~buf
~pos
~len
Reader.
(
bytes
1
>>
=
fun
msg_typ
->
int32
>>
=
fun
len
-> dispatch_backend_msg (
Int32.
to_int len
-
4
) msg_typ.[
0
])
in
match
res
with
|
Ok
(
frame
,
pos'
) -> (
match
backend_msg' pos' buf (len
-
(pos'
-
pos))
with
|
Ok
(
frames
,
pos
) ->
Ok
(frame :: frames, pos)
|
Error
(
frames
, `Length,
_
) ->
Ok
(frame :: frames, pos')
|
Error
(
frames
,
err
,
pos
) ->
Error
(frame :: frames, err, pos))
|
Error
(
err
,
_
) ->
Error
(
[]
, err, pos)
let
run_backend_msg
t
pos
buf
len
=
match
backend_msg' pos buf len
with
|
Error
(
[]
, (
`Unknown_type
_
as
err
),
_
)
|
Error
(
[]
, (`Invalid_frame
as
err
),
_
) ->
Error
err
|
Error
(
frames
, `Needed_bytes
n
,
pos
) ->
assert
(n
>
0
);
Buffer.
clear t.buf;
Buffer.
add_subbytes t.buf buf pos (len
-
pos);
t.needed_bytes
<
-
n;
Ok
frames
|
Error
(
frames
,
_
,
pos
)
|
Ok
(
frames
,
pos
) ->
Buffer.
clear t.buf;
Buffer.
add_subbytes t.buf buf pos (len
-
pos);
Ok
frames
let
backend_msg
t
~
pos
~
len
buf
=
if
Buffer.
length t.buf
=
0
&&
t.needed_bytes
<
0
then
run_backend_msg t pos buf len
else
if
t.needed_bytes
<
0
then
(
Buffer.
add_subbytes t.buf buf pos len;
let
b
=
Buffer.
to_bytes t.buf
in
run_backend_msg t
0
b (
Bytes.
length b))
else
(
Buffer.
add_subbytes t.buf buf pos len;
t.needed_bytes
<
-
t.needed_bytes
-
len;
(*
<= 0, not < 0: when exactly the needed bytes arrive the frame is complete
and must be decoded. Treating exactly-0 as "still waiting" stranded the
buffered frame and left needed_bytes at Some 0, hanging the read. Reset
to -1 first since run_backend_msg only re-arms needed_bytes if a *later*
frame is still partial.
*)
if
t.needed_bytes
<
=
0
then
(
t.needed_bytes
<
-
-
1
;
let
b
=
Buffer.
to_bytes t.buf
in
run_backend_msg t
0
b (
Bytes.
length b))
else
Ok
[]
)
let
frontend_msg
_t
~
pos
:
_
~
len
:
_
_buf
=
failwith
"
nyi
"
let
needed_bytes
t
=
if
t.needed_bytes
<
0
then
None
else
Some
t.needed_bytes
let
buffer_length
t
=
Buffer.
length t.buf
end
module
Encode
=
struct
let
backend_msg
_buf
_frame
=
failwith
"
nyi
"
let
frontend_msg'
=
let
open
Writer
in
let
open
Frame.Frontend
in
function
|
Bind
{ portal; stmt; format_codes; values; result_format_codes }
->
msg_code
'B'
>>
=
fun
()
->
string
portal
>>
=
fun
()
->
string
stmt
>>
=
fun
()
->
int16 (
List.
length format_codes)
>>
=
fun
()
->
iter (
fun
b
-> int16 (
if
b
then
1
else
0
)) format_codes
>>
=
fun
()
->
int16 (
List.
length values)
>>
=
fun
()
->
iter
(
function
|
None
->
int32
(
Int32.
of_int (
-
1
))
|
Some
s
->
int32
(
Int32.
of_int (
String.
length s))
>>
=
fun
()
-> bytes s)
values
>>
=
fun
()
->
int16 (
List.
length result_format_codes)
>>
=
fun
()
-> iter (
fun
b
-> int16 (
if
b
then
1
else
0
)) result_format_codes
|
CancelRequest
{ pid; secret_key }
->
int32
(
Int32.
of_string
"
80877102
"
)
>>
=
fun
()
->
int32
pid
>>
=
fun
()
->
int32
secret_key
|
Close
{ typ; name }
-> msg_code
'C'
>>
=
fun
()
-> chr typ
>>
=
fun
()
->
string
name
|
CopyData
{ data }
-> msg_code
'd'
>>
=
fun
()
-> bytes data
|
CopyDone
-> msg_code
'c'
|
CopyFail
{ message }
-> msg_code
'f'
>>
=
fun
()
->
string
message
|
Describe
{ typ; name }
-> msg_code
'D'
>>
=
fun
()
-> chr typ
>>
=
fun
()
->
string
name
|
Execute
{ portal; max_rows }
->
msg_code
'E'
>>
=
fun
()
->
string
portal
>>
=
fun
()
->
int32
max_rows
|
Flush
-> msg_code
'H'
|
FunctionCall
-> failwith
"
nyi
"
|
GSSResponse
{ data }
-> msg_code
'p'
>>
=
fun
()
-> bytes data
|
Parse
{ stmt; query; data_types }
->
msg_code
'P'
>>
=
fun
()
->
string
stmt
>>
=
fun
()
->
string
query
>>
=
fun
()
-> int16 (
List.
length data_types)
>>
=
fun
()
-> iter
int32
data_types
|
PasswordMessage
{ password }
-> msg_code
'p'
>>
=
fun
()
->
string
password
|
Query
{ query }
-> msg_code
'Q'
>>
=
fun
()
->
string
query
|
SASLInitialResponse
{ auth_mechanism; data }
->
msg_code
'p'
>>
=
fun
()
->
string
auth_mechanism
>>
=
fun
()
->
int32
(
Int32.
of_int (
String.
length data))
>>
=
fun
()
-> bytes data
|
SASLResponse
{ data }
-> msg_code
'p'
>>
=
fun
()
-> bytes data
|
SSLRequest
->
int32
(
Int32.
of_string
"
80877103
"
)
|
StartupMessage
{ msgs }
->
int32
(
Int32.
of_string
"
196608
"
)
>>
=
fun
()
->
iter (
fun
(
k
,
v
) ->
string
k
>>
=
fun
()
->
string
v) msgs
>>
=
fun
()
-> bytes
"
\000
"
|
Sync
-> msg_code
'S'
|
Terminate
-> msg_code
'X'
let
frontend_msg
buf
frame
=
let
writer
=
frontend_msg' frame
in
Writer.
run buf writer
end
module
Binary_value
=
struct
module
Encode
=
struct
let
int2
n
=
let
buf
=
Bytes.
create
2
in
EndianBytes.BigEndian.
set_int16 buf
0
n;
Bytes.
to_string buf
let
int4
n
=
let
buf
=
Bytes.
create
4
in
EndianBytes.BigEndian.
set_int32 buf
0
n;
Bytes.
to_string buf
let
int8
n
=
let
buf
=
Bytes.
create
8
in
EndianBytes.BigEndian.
set_int64 buf
0
n;
Bytes.
to_string buf
let
float4
f
=
int4 (
Int32.
bits_of_float f)
let
float8
f
=
int8 (
Int64.
bits_of_float f)
let
bool
b
=
if
b
then
"
\001
"
else
"
\000
"
end
module
Decode
=
struct
let
int2
s
=
if
String.
length s
=
2
then
Some
(
EndianString.BigEndian.
get_int16 s
0
)
else
None
let
int4
s
=
if
String.
length s
=
4
then
Some
(
EndianString.BigEndian.
get_int32 s
0
)
else
None
let
int8
s
=
if
String.
length s
=
8
then
Some
(
EndianString.BigEndian.
get_int64 s
0
)
else
None
let
float4
s
=
Option.
map
Int32.
float_of_bits (int4 s)
let
float8
s
=
Option.
map
Int64.
float_of_bits (int8 s)
let
bool
s
=
if
String.
length s
=
1
then
Some
(
Char.
code s.[
0
]
<>
0
)
else
None
end
end
Back
|
FazBrowse Home
|
New Git URL