include "sys.m";
sys: Sys;
include "bufio.m";
bufio : Bufio;
Iobuf : import bufio;
include "keyring.m";
keyring: Keyring;
Pg: module { #pg.b
PATH: con "/usr/maht/pg/pg.dis";
bytes_to_int : fn(b : array of byte) : (int, int);
bytes_to_big : fn(b : array of byte) : (int, big);
int_to_bytes : fn(i, length : int) : array of byte;
big_to_bytes : fn(i : big, length : int) : array of byte;
Recordset : adt {
fields : array of ref Field;
rows : array of array of array of byte;
to_string : fn(r: self ref Recordset) : string;
};
Data : adt {
bytes : array of byte;
ptr : int;
extend_bytes: fn(data : self ref Data, n : int) : int;
append: fn(data : self ref Data, bytes : array of byte) : int;
write: fn (data : self ref Data, txt : string) : int;
md5: fn(data : self ref Data) : string;
puts: fn (data : self ref Data, txt : string) : int;
put_notnil_s: fn (data : self ref Data, key, value : string) : int;
send : fn(data : self ref Data, io : ref Iobuf, tag : int ) : int;
to_string : fn(data : self ref Data) : string;
};
Field : adt {
name : string;
table_oid : int; # int32 - zero if not known
column_attribute_number : int; # int16
data_type_oid : int; # int32
data_type_size : int; # int16 -ive means variable width
type_modifier : int; # int32 type specific
format_code : int; # 0 for text 1 for binary
read: fn(f: self ref Field, io : ref Iobuf);
to_string : fn(data : self ref Field) : string;
};
Response : adt {
code : int;
data : string;
read : fn (r : self ref Response, io : ref Iobuf) : int;
to_string : fn (r : self ref Response) : string;
};
Parameter : adt {
key : string;
value : string;
read : fn (r : self ref Parameter, io : ref Iobuf) : int;
to_string : fn (p : self ref Parameter) : string;
};
Frontend_Message : adt {
tag : int;
pick {
StartupMessage => # nil
protocol_version : int; # 196608
user : string;
database : string;
options : string;
parameters : string;
PasswordMessage => # p
password : string;
Query => # Q
sql : string;
CopyData => # d
data : array of byte;
CopyFail => # f
err : string;
CopyDone => # c
Parse => #P
name : string;
query : string;
data_type_oids : array of int;
Bind => # B
portal : string;
name : string;
parameter_format_codes : array of int;
parameters : array of array of byte;
result_format_codes : array of int;
Execute => # E
portal : string;
rows_to_return : int;
Sync => # S
Describe => # D
item_type : byte; # 'S' or 'P'
name : string;
Close => # C
item_type: byte; # 'S' or 'P'
name : string;
Flush => # H
Terminate => # X
}
};
Backend_Message :adt {
tag : int;
to_string : fn(b_msg : self ref Backend_Message) : string;
pick {
Error => # E
responses : list of ref Response;
NoticeResponse => # N
responses : list of ref Response;
Authentication => # R
auth_type : int;
# 0 AuthenticationOK,
# 2 Kerberos V5
# 3 Clear Text
# 4 Crypt (with 2 byte salt)
# 5 MD5 (with 4 byte salt)
# 6 SCM Credential
salt : array of byte;
ReadyForQuery => # Z
status : int;
RowDescription => # T
fields : array of ref Field;
DataRow => # D
columns : array of array of byte;
CopyData => # d
data : array of byte;
CopyDone => # c
CopyInResponse => # G
copy_format : byte; # 0 or 1
format_codes : array of int;
CopyOutResponse => # H
copy_format : byte; # 0 or 1
format_codes : array of int;
CommandComplete => # C
cmd : string;
oid : int;
rows : int;
ParseComplete => # 1
BindComplete => # 2
CloseComplete => # 3
PortalSuspended => # s
EmptyQueryResponse => # I
NoData => # n
ParameterDescription => # t
oids : array of int;
Unknown =>
data : array of byte;
}
};
not_implemented : adt {
id : int;
pick {
V => # FunctionCallResponse
length : int; # -1 for NULL
data : array of byte;
A => # NotificationResponse
process_id : int;
condition : string;
info : string; # expected to be always empty atm.
}
};
Connection: adt {
debug : int;
user, database, password : string;
fd : ref Sys->FD;
notices : chan of ref Backend_Message;
rx : chan of ref Backend_Message;
tx : chan of ref Frontend_Message;
status : int;
process_id : int;
key : int;
parameters : list of ref Parameter;
connect : fn(connection: self ref Connection, ip, port, options, parameters : string) : int;
set_parameter : fn(c : self ref Connection, p : ref Parameter);
query : fn(c: self ref Connection, sql : string) : ref Recordset;
parse : fn(c: self ref Connection, name: string, sql : string, data_type_oids : array of int) : int;
describe : fn(c: self ref Connection, item_type : byte, name : string);
execute : fn(c: self ref Connection, portal, name : string, parameter_format_codes : array of int, parameters : array of array of byte, result_format_codes : array of int, rows_to_return : int) : ref Recordset;
disconnect : fn(c: self ref Connection);
};
};
|