1 module database.postgresql.protocol;
2 
3 //https://www.postgresql.org/docs/10/static/protocol-message-formats.html
4 enum OutputMessageType : ubyte
5 {
6     Bind             = 'B',
7     Close            = 'C',
8     CopyData         = 'd',
9     CopyDone         = 'c',
10     CopyFail         = 'f',
11     Describe         = 'D',
12     Execute          = 'E',
13     Flush            = 'H',
14     FunctionCall     = 'F',
15     Parse            = 'P',
16     PasswordMessage  = 'p',
17     Query            = 'Q',
18     Sync             = 'S',
19     Terminate        = 'T'
20 }
21 
22 enum InputMessageType : ubyte
23 {
24     Authentication       = 'R',
25     BackendKeyData       = 'K',
26     BindComplete         = '2',
27     CloseComplete        = '3',
28     CommandComplete      = 'C',
29     CopyData             = 'd',
30     CopyDone             = 'c',
31     CopyInResponse       = 'G',
32     CopyOutResponse      = 'H',
33     CopyBothResponse     = 'W',
34     DataRow              = 'D',
35     EmptyQueryResponse   = 'I',
36     ErrorResponse        = 'E',
37     FunctionCallResponse = 'V',
38     NoData               = 'n',
39     NoticeResponse       = 'N',
40     NotificationResponse = 'A',
41     ParameterDescription = 't',
42     ParameterStatus      = 'S',
43     ParseComplete        = '1',
44     PortalSuspended      = 's',
45     ReadyForQuery        = 'Z',
46     RowDescription       = 'T'
47 }
48 
49 enum TransactionStatus : ubyte
50 {
51     Idle                 = 'I',
52     Inside               = 'T',
53     Error                = 'E',
54 }
55 
56 enum FormatCode : ubyte
57 {
58     Text     = 0,
59     Binary     = 1,
60 }
61 
62 enum NoticeMessageField : ubyte
63 {
64     SeverityLocal       = 'S',
65     Severity            = 'V',
66     Code                = 'C',
67     Message             = 'M',
68     Detail              = 'D',
69     Hint                = 'H',
70     Position            = 'P',
71     InternalPosition    = 'p',
72     InternalQuery       = 'q',
73     Where               = 'W',
74     Schema              = 's',
75     Table               = 't',
76     Column              = 'c',
77     DataType            = 'd',
78     Constraint          = 'n',
79     File                = 'F',
80     Line                = 'L',
81     Routine             = 'R',
82 }
83 
84 // https://github.com/postgres/postgres/blob/master/src/include/catalog/pg_type.dat
85 enum PgColumnTypes : uint
86 {
87     NULL         = 0,
88     BOOL         = 16,
89     BYTEA        = 17,
90     CHAR         = 18,
91     NAME         = 19,
92     INT8         = 20,
93     INT2         = 21,
94     // INTVEC2       = 22,
95     INT4         = 23,
96     //REGPROC        = 24,
97     TEXT         = 25,
98     // OID           = 26,
99     // TID           = 27,
100     // XID           = 28,
101     // CID           = 29,
102     // OIDARRAY      = 30,
103 
104     // PG_TYPE       = 71,
105     // PG_ATTRIBUTE  = 75,
106     // PG_PROC       = 81,
107     // PG_CLASS      = 83,
108 
109     JSON         = 114,
110     XML          = 142,
111 
112     POINT        = 600,
113     LSEG         = 601,
114     PATH         = 602,
115     BOX          = 603,
116     POLYGON      = 604,
117     LINE         = 628,
118 
119     REAL         = 700,
120     DOUBLE           = 701,
121     // ABSTIME       = 702,
122     // RELTIME       = 703,
123     TINTERVAL    = 704,
124     UNKNOWN      = 705,
125     CIRCLE       = 718,
126     MONEY        = 790,
127 
128     MACADDR      = 829,
129     INET         = 869,
130     CIDR         = 650,
131     MACADDR8     = 774,
132 
133     CHARA        = 1042,
134     VARCHAR      = 1043,
135     DATE         = 1082,
136     TIME         = 1083,
137 
138     TIMESTAMP    = 1114,
139     TIMESTAMPTZ  = 1184,
140     INTERVAL     = 1186,
141 
142     TIMETZ       = 1266,
143 
144     BIT          = 1560,
145     VARBIT       = 1562,
146 
147     NUMERIC      = 1700,
148     // REFCURSOR     = 1790,
149 
150     // REGPROCEDURE  = 2202,
151     // REGOPER       = 2203,
152     // REGOPERATOR   = 2204,
153     // REGCLASS      = 2205,
154     // REGTYPE       = 2206,
155     // REGROLE       = 4096,
156     // REGNAMESPACE  = 4089,
157 
158     UUID         = 2950,
159     JSONB        = 3802
160 }
161 
162 auto columnTypeName(PgColumnTypes type)
163 {
164     final switch (type) with (PgColumnTypes)
165     {
166         case NULL:            return "null";
167         case BOOL:            return "bool";
168         case BYTEA:           return "bytea";
169         case CHAR:            return "char";
170         case NAME:            return "name";
171         case INT8:            return "int8";
172         case INT2:            return "int2";
173         case INT4:            return "int4";
174         case TEXT:            return "text";
175         case JSON:            return "json";
176         case XML:             return "xml";
177         case POINT:           return "point";
178         case LSEG:            return "lseg";
179         case PATH:            return "path";
180         case BOX:             return "box";
181         case POLYGON:         return "polygon";
182         case LINE:            return "line";
183         case REAL:            return "real";
184         case DOUBLE:          return "double precision";
185         case TINTERVAL:       return "tinterval";
186         case UNKNOWN:         return "unknown";
187         case CIRCLE:          return "circle";
188         case MONEY:           return "money";
189         case MACADDR:         return "macaddr";
190         case INET:            return "inet";
191         case CIDR:            return "cidr";
192         case MACADDR8:        return "macaddr8";
193         case CHARA:           return "char(n)";
194         case VARCHAR:         return "varchar";
195         case DATE:            return "date";
196         case TIME:            return "time";
197         case TIMESTAMP:       return "timestamp";
198         case TIMESTAMPTZ:     return "timestamptz";
199         case INTERVAL:        return "interval";
200         case TIMETZ:          return "timetz";
201         case BIT:             return "bit";
202         case VARBIT:          return "varbit";
203         case NUMERIC:         return "numeric";
204         case UUID:            return "uuid";
205         case JSONB:           return "jsonb";
206     }
207 }