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.
@@ -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 = trilogy_sock_discard(conn->socket);
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