trilogy 2.4.0 → 2.5.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.
- checksums.yaml +4 -4
- data/README.md +14 -5
- data/Rakefile +6 -0
- data/ext/trilogy-ruby/cast.c +0 -4
- data/ext/trilogy-ruby/cext.c +106 -34
- data/ext/trilogy-ruby/inc/trilogy/blocking.h +118 -0
- data/ext/trilogy-ruby/inc/trilogy/builder.h +60 -0
- data/ext/trilogy-ruby/inc/trilogy/client.h +214 -0
- data/ext/trilogy-ruby/inc/trilogy/error.h +4 -1
- data/ext/trilogy-ruby/inc/trilogy/protocol.h +269 -3
- data/ext/trilogy-ruby/inc/trilogy/reader.h +4 -0
- data/ext/trilogy-ruby/inc/trilogy/socket.h +2 -1
- data/ext/trilogy-ruby/src/blocking.c +117 -0
- data/ext/trilogy-ruby/src/builder.c +63 -0
- data/ext/trilogy-ruby/src/client.c +180 -17
- data/ext/trilogy-ruby/src/protocol.c +503 -0
- data/ext/trilogy-ruby/src/reader.c +38 -0
- data/ext/trilogy-ruby/src/socket.c +96 -39
- data/lib/trilogy/encoding.rb +97 -0
- data/lib/trilogy/error.rb +118 -0
- data/lib/trilogy/result.rb +33 -0
- data/lib/trilogy/version.rb +1 -1
- data/lib/trilogy.rb +9 -239
- data/trilogy.gemspec +1 -1
- metadata +6 -3
@@ -39,6 +39,8 @@ int trilogy_builder_init(trilogy_builder_t *builder, trilogy_buffer_t *buff, uin
|
|
39
39
|
builder->buffer->len = 0;
|
40
40
|
|
41
41
|
builder->seq = seq;
|
42
|
+
builder->packet_length = 0;
|
43
|
+
builder->packet_max_length = SIZE_MAX;
|
42
44
|
|
43
45
|
return write_header(builder);
|
44
46
|
}
|
@@ -60,10 +62,15 @@ void trilogy_builder_finalize(trilogy_builder_t *builder)
|
|
60
62
|
|
61
63
|
int trilogy_builder_write_uint8(trilogy_builder_t *builder, uint8_t val)
|
62
64
|
{
|
65
|
+
if (builder->packet_length >= builder->packet_max_length - 1) {
|
66
|
+
return TRILOGY_MAX_PACKET_EXCEEDED;
|
67
|
+
}
|
68
|
+
|
63
69
|
CHECKED(trilogy_buffer_expand(builder->buffer, 1));
|
64
70
|
|
65
71
|
builder->buffer->buff[builder->buffer->len++] = val;
|
66
72
|
builder->fragment_length++;
|
73
|
+
builder->packet_length++;
|
67
74
|
|
68
75
|
if (builder->fragment_length == TRILOGY_MAX_PACKET_LEN) {
|
69
76
|
CHECKED(write_continuation_header(builder));
|
@@ -113,6 +120,44 @@ int trilogy_builder_write_uint64(trilogy_builder_t *builder, uint64_t val)
|
|
113
120
|
return TRILOGY_OK;
|
114
121
|
}
|
115
122
|
|
123
|
+
int trilogy_builder_write_float(trilogy_builder_t *builder, float val)
|
124
|
+
{
|
125
|
+
union {
|
126
|
+
float f;
|
127
|
+
uint32_t u;
|
128
|
+
} float_val;
|
129
|
+
|
130
|
+
float_val.f = val;
|
131
|
+
|
132
|
+
CHECKED(trilogy_builder_write_uint8(builder, float_val.u & 0xff));
|
133
|
+
CHECKED(trilogy_builder_write_uint8(builder, (float_val.u >> 8) & 0xff));
|
134
|
+
CHECKED(trilogy_builder_write_uint8(builder, (float_val.u >> 16) & 0xff));
|
135
|
+
CHECKED(trilogy_builder_write_uint8(builder, (float_val.u >> 24) & 0xff));
|
136
|
+
|
137
|
+
return TRILOGY_OK;
|
138
|
+
}
|
139
|
+
|
140
|
+
int trilogy_builder_write_double(trilogy_builder_t *builder, double val)
|
141
|
+
{
|
142
|
+
union {
|
143
|
+
double d;
|
144
|
+
uint64_t u;
|
145
|
+
} double_val;
|
146
|
+
|
147
|
+
double_val.d = val;
|
148
|
+
|
149
|
+
CHECKED(trilogy_builder_write_uint8(builder, double_val.u & 0xff));
|
150
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 8) & 0xff));
|
151
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 16) & 0xff));
|
152
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 24) & 0xff));
|
153
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 32) & 0xff));
|
154
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 40) & 0xff));
|
155
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 48) & 0xff));
|
156
|
+
CHECKED(trilogy_builder_write_uint8(builder, (double_val.u >> 56) & 0xff));
|
157
|
+
|
158
|
+
return TRILOGY_OK;
|
159
|
+
}
|
160
|
+
|
116
161
|
int trilogy_builder_write_lenenc(trilogy_builder_t *builder, uint64_t val)
|
117
162
|
{
|
118
163
|
if (val < 251) {
|
@@ -137,6 +182,10 @@ int trilogy_builder_write_buffer(trilogy_builder_t *builder, const void *data, s
|
|
137
182
|
|
138
183
|
size_t fragment_remaining = TRILOGY_MAX_PACKET_LEN - builder->fragment_length;
|
139
184
|
|
185
|
+
if (builder->packet_length >= builder->packet_max_length - len) {
|
186
|
+
return TRILOGY_MAX_PACKET_EXCEEDED;
|
187
|
+
}
|
188
|
+
|
140
189
|
// if this buffer write is not going to straddle a fragment boundary:
|
141
190
|
if (len < fragment_remaining) {
|
142
191
|
CHECKED(trilogy_buffer_expand(builder->buffer, len));
|
@@ -145,6 +194,7 @@ int trilogy_builder_write_buffer(trilogy_builder_t *builder, const void *data, s
|
|
145
194
|
|
146
195
|
builder->buffer->len += len;
|
147
196
|
builder->fragment_length += len;
|
197
|
+
builder->packet_length += len;
|
148
198
|
|
149
199
|
return TRILOGY_OK;
|
150
200
|
}
|
@@ -157,6 +207,7 @@ int trilogy_builder_write_buffer(trilogy_builder_t *builder, const void *data, s
|
|
157
207
|
|
158
208
|
builder->buffer->len += fragment_remaining;
|
159
209
|
builder->fragment_length += fragment_remaining;
|
210
|
+
builder->packet_length += fragment_remaining;
|
160
211
|
|
161
212
|
ptr += fragment_remaining;
|
162
213
|
len -= fragment_remaining;
|
@@ -172,6 +223,7 @@ int trilogy_builder_write_buffer(trilogy_builder_t *builder, const void *data, s
|
|
172
223
|
|
173
224
|
builder->buffer->len += len;
|
174
225
|
builder->fragment_length += len;
|
226
|
+
builder->packet_length += len;
|
175
227
|
}
|
176
228
|
|
177
229
|
return TRILOGY_OK;
|
@@ -195,4 +247,15 @@ int trilogy_builder_write_string(trilogy_builder_t *builder, const char *data)
|
|
195
247
|
return TRILOGY_OK;
|
196
248
|
}
|
197
249
|
|
250
|
+
int trilogy_builder_set_max_packet_length(trilogy_builder_t *builder, size_t max_length)
|
251
|
+
{
|
252
|
+
if (builder->packet_length > max_length) {
|
253
|
+
return TRILOGY_MAX_PACKET_EXCEEDED;
|
254
|
+
}
|
255
|
+
|
256
|
+
builder->packet_max_length = max_length;
|
257
|
+
|
258
|
+
return TRILOGY_OK;
|
259
|
+
}
|
260
|
+
|
198
261
|
#undef CHECKED
|
@@ -1,4 +1,3 @@
|
|
1
|
-
#include <errno.h>
|
2
1
|
#include <fcntl.h>
|
3
2
|
|
4
3
|
#include "trilogy/client.h"
|
@@ -60,6 +59,10 @@ static int begin_command_phase(trilogy_builder_t *builder, trilogy_conn_t *conn,
|
|
60
59
|
return rc;
|
61
60
|
}
|
62
61
|
|
62
|
+
if (conn->socket->opts.max_allowed_packet > 0) {
|
63
|
+
trilogy_builder_set_max_packet_length(builder, conn->socket->opts.max_allowed_packet);
|
64
|
+
}
|
65
|
+
|
63
66
|
conn->packet_parser.sequence_number = seq + 1;
|
64
67
|
|
65
68
|
return 0;
|
@@ -72,11 +75,6 @@ static int read_packet(trilogy_conn_t *conn)
|
|
72
75
|
|
73
76
|
if (nread < 0) {
|
74
77
|
int rc = (int)nread;
|
75
|
-
if (rc == TRILOGY_SYSERR) {
|
76
|
-
if (errno == EINTR || errno == EAGAIN) {
|
77
|
-
return TRILOGY_AGAIN;
|
78
|
-
}
|
79
|
-
}
|
80
78
|
return rc;
|
81
79
|
}
|
82
80
|
|
@@ -158,16 +156,6 @@ int trilogy_flush_writes(trilogy_conn_t *conn)
|
|
158
156
|
|
159
157
|
if (bytes < 0) {
|
160
158
|
int rc = (int)bytes;
|
161
|
-
if (rc == TRILOGY_SYSERR) {
|
162
|
-
if (errno == EINTR || errno == EAGAIN) {
|
163
|
-
return TRILOGY_AGAIN;
|
164
|
-
}
|
165
|
-
|
166
|
-
if (errno == EPIPE) {
|
167
|
-
return TRILOGY_CLOSED_CONNECTION;
|
168
|
-
}
|
169
|
-
}
|
170
|
-
|
171
159
|
return rc;
|
172
160
|
}
|
173
161
|
|
@@ -766,11 +754,186 @@ void trilogy_free(trilogy_conn_t *conn)
|
|
766
754
|
|
767
755
|
int trilogy_discard(trilogy_conn_t *conn)
|
768
756
|
{
|
769
|
-
int rc =
|
757
|
+
int rc = trilogy_sock_shutdown(conn->socket);
|
770
758
|
if (rc == TRILOGY_OK) {
|
771
759
|
trilogy_free(conn);
|
772
760
|
}
|
773
761
|
return rc;
|
774
762
|
}
|
775
763
|
|
764
|
+
int trilogy_stmt_prepare_send(trilogy_conn_t *conn, const char *stmt, size_t stmt_len)
|
765
|
+
{
|
766
|
+
trilogy_builder_t builder;
|
767
|
+
int err = begin_command_phase(&builder, conn, 0);
|
768
|
+
if (err < 0) {
|
769
|
+
return err;
|
770
|
+
}
|
771
|
+
|
772
|
+
err = trilogy_build_stmt_prepare_packet(&builder, stmt, stmt_len);
|
773
|
+
if (err < 0) {
|
774
|
+
return err;
|
775
|
+
}
|
776
|
+
|
777
|
+
return begin_write(conn);
|
778
|
+
}
|
779
|
+
|
780
|
+
int trilogy_stmt_prepare_recv(trilogy_conn_t *conn, trilogy_stmt_t *stmt_out)
|
781
|
+
{
|
782
|
+
int err = read_packet(conn);
|
783
|
+
|
784
|
+
if (err < 0) {
|
785
|
+
return err;
|
786
|
+
}
|
787
|
+
|
788
|
+
switch (current_packet_type(conn)) {
|
789
|
+
case TRILOGY_PACKET_OK: {
|
790
|
+
err = trilogy_parse_stmt_ok_packet(conn->packet_buffer.buff, conn->packet_buffer.len, stmt_out);
|
791
|
+
|
792
|
+
if (err < 0) {
|
793
|
+
return err;
|
794
|
+
}
|
795
|
+
|
796
|
+
conn->warning_count = stmt_out->warning_count;
|
797
|
+
|
798
|
+
return TRILOGY_OK;
|
799
|
+
}
|
800
|
+
|
801
|
+
case TRILOGY_PACKET_ERR:
|
802
|
+
return read_err_packet(conn);
|
803
|
+
|
804
|
+
default:
|
805
|
+
return TRILOGY_UNEXPECTED_PACKET;
|
806
|
+
}
|
807
|
+
}
|
808
|
+
|
809
|
+
int trilogy_stmt_execute_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt, uint8_t flags, trilogy_binary_value_t *binds)
|
810
|
+
{
|
811
|
+
trilogy_builder_t builder;
|
812
|
+
int err = begin_command_phase(&builder, conn, 0);
|
813
|
+
if (err < 0) {
|
814
|
+
return err;
|
815
|
+
}
|
816
|
+
|
817
|
+
err = trilogy_build_stmt_execute_packet(&builder, stmt->id, flags, binds, stmt->parameter_count);
|
818
|
+
|
819
|
+
if (err < 0) {
|
820
|
+
return err;
|
821
|
+
}
|
822
|
+
|
823
|
+
conn->packet_parser.sequence_number = builder.seq;
|
824
|
+
|
825
|
+
return begin_write(conn);
|
826
|
+
}
|
827
|
+
|
828
|
+
int trilogy_stmt_execute_recv(trilogy_conn_t *conn, uint64_t *column_count_out)
|
829
|
+
{
|
830
|
+
int err = read_packet(conn);
|
831
|
+
|
832
|
+
if (err < 0) {
|
833
|
+
return err;
|
834
|
+
}
|
835
|
+
|
836
|
+
switch (current_packet_type(conn)) {
|
837
|
+
case TRILOGY_PACKET_OK:
|
838
|
+
return read_ok_packet(conn);
|
839
|
+
|
840
|
+
case TRILOGY_PACKET_ERR:
|
841
|
+
return read_err_packet(conn);
|
842
|
+
|
843
|
+
default: {
|
844
|
+
trilogy_result_packet_t result_packet;
|
845
|
+
err = trilogy_parse_result_packet(conn->packet_buffer.buff, conn->packet_buffer.len, &result_packet);
|
846
|
+
|
847
|
+
if (err < 0) {
|
848
|
+
return err;
|
849
|
+
}
|
850
|
+
|
851
|
+
conn->column_count = result_packet.column_count;
|
852
|
+
*column_count_out = result_packet.column_count;
|
853
|
+
|
854
|
+
return TRILOGY_OK;
|
855
|
+
}
|
856
|
+
}
|
857
|
+
}
|
858
|
+
|
859
|
+
int trilogy_stmt_bind_data_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt, uint16_t param_num, uint8_t *data,
|
860
|
+
size_t data_len)
|
861
|
+
{
|
862
|
+
trilogy_builder_t builder;
|
863
|
+
int err = begin_command_phase(&builder, conn, 0);
|
864
|
+
if (err < 0) {
|
865
|
+
return err;
|
866
|
+
}
|
867
|
+
|
868
|
+
err = trilogy_build_stmt_bind_data_packet(&builder, stmt->id, param_num, data, data_len);
|
869
|
+
|
870
|
+
if (err < 0) {
|
871
|
+
return err;
|
872
|
+
}
|
873
|
+
|
874
|
+
return begin_write(conn);
|
875
|
+
}
|
876
|
+
|
877
|
+
int trilogy_stmt_read_row(trilogy_conn_t *conn, trilogy_stmt_t *stmt, trilogy_column_packet_t *columns,
|
878
|
+
trilogy_binary_value_t *values_out)
|
879
|
+
{
|
880
|
+
int err = read_packet(conn);
|
881
|
+
|
882
|
+
if (err < 0) {
|
883
|
+
return err;
|
884
|
+
}
|
885
|
+
|
886
|
+
if (conn->capabilities & TRILOGY_CAPABILITIES_DEPRECATE_EOF && current_packet_type(conn) == TRILOGY_PACKET_EOF) {
|
887
|
+
if ((err = read_ok_packet(conn)) != TRILOGY_OK) {
|
888
|
+
return err;
|
889
|
+
}
|
890
|
+
|
891
|
+
return TRILOGY_EOF;
|
892
|
+
} else if (current_packet_type(conn) == TRILOGY_PACKET_EOF && conn->packet_buffer.len < 9) {
|
893
|
+
return read_eof_packet(conn);
|
894
|
+
} else if (current_packet_type(conn) == TRILOGY_PACKET_ERR) {
|
895
|
+
return read_err_packet(conn);
|
896
|
+
} else {
|
897
|
+
return trilogy_parse_stmt_row_packet(conn->packet_buffer.buff, conn->packet_buffer.len, columns,
|
898
|
+
stmt->column_count, values_out);
|
899
|
+
}
|
900
|
+
}
|
901
|
+
|
902
|
+
int trilogy_stmt_reset_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt)
|
903
|
+
{
|
904
|
+
trilogy_builder_t builder;
|
905
|
+
int err = begin_command_phase(&builder, conn, 0);
|
906
|
+
if (err < 0) {
|
907
|
+
return err;
|
908
|
+
}
|
909
|
+
|
910
|
+
err = trilogy_build_stmt_reset_packet(&builder, stmt->id);
|
911
|
+
if (err < 0) {
|
912
|
+
return err;
|
913
|
+
}
|
914
|
+
|
915
|
+
return begin_write(conn);
|
916
|
+
}
|
917
|
+
|
918
|
+
int trilogy_stmt_reset_recv(trilogy_conn_t *conn) {
|
919
|
+
return read_generic_response(conn);
|
920
|
+
}
|
921
|
+
|
922
|
+
int trilogy_stmt_close_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt)
|
923
|
+
{
|
924
|
+
trilogy_builder_t builder;
|
925
|
+
int err = begin_command_phase(&builder, conn, 0);
|
926
|
+
if (err < 0) {
|
927
|
+
return err;
|
928
|
+
}
|
929
|
+
|
930
|
+
err = trilogy_build_stmt_close_packet(&builder, stmt->id);
|
931
|
+
|
932
|
+
if (err < 0) {
|
933
|
+
return err;
|
934
|
+
}
|
935
|
+
|
936
|
+
return begin_write(conn);
|
937
|
+
}
|
938
|
+
|
776
939
|
#undef CHECKED
|