trilogy 2.4.1 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +110 -33
- 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 +266 -2
- 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 -244
- 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
|