agoo 2.7.0 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/ext/agoo/agoo.c +25 -20
- data/ext/agoo/con.c +35 -35
- data/ext/agoo/error_stream.c +10 -8
- data/ext/agoo/gqlcobj.c +25 -0
- data/ext/agoo/gqlcobj.h +14 -0
- data/ext/agoo/gqleval.c +24 -11
- data/ext/agoo/gqleval.h +2 -0
- data/ext/agoo/gqlintro.c +30 -54
- data/ext/agoo/gqljson.c +36 -32
- data/ext/agoo/gqlvalue.c +105 -52
- data/ext/agoo/gqlvalue.h +3 -0
- data/ext/agoo/graphql.c +110 -80
- data/ext/agoo/graphql.h +17 -13
- data/ext/agoo/log.c +16 -12
- data/ext/agoo/rack_logger.c +4 -1
- data/ext/agoo/request.c +7 -9
- data/ext/agoo/rgraphql.c +41 -30
- data/ext/agoo/rresponse.c +7 -6
- data/ext/agoo/rserver.c +35 -22
- data/ext/agoo/sdl.c +234 -117
- data/ext/agoo/server.c +5 -5
- data/ext/agoo/text.c +23 -9
- data/lib/agoo/version.rb +1 -1
- data/test/graphql_test.rb +33 -27
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5771b6b916b39b35a7ddb198b3c80191b69cfd0f0d8d8fd792d1a1b90cc741c
|
4
|
+
data.tar.gz: 2503a29f723db8fa63b0a3bb6f64879046f4f31b2d15c594d4e22e5c2d745e44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0deeaf2727b3c729229420953662854de902e8a173d7a0ccabbe9e42ea2d2d269c66275520e8950c73f4ef7a758b271456f753695aea0bc8492cf1fbb66fbde9
|
7
|
+
data.tar.gz: 4fe4ce7b04976e446f9f0f3c051e360041c70d6a65d2d6bb1f5ab30c9cec1955326ead8caed0a66bd5f403ada280d61c645eca3509e5568c73940a034258d51a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
### 2.8.0 - 2019-02-19
|
4
|
+
|
5
|
+
Extend GraphQL
|
6
|
+
|
7
|
+
- Add support for the Graphql `extend` functionality.
|
8
|
+
|
9
|
+
- Add the ID base scalar type.
|
10
|
+
|
11
|
+
- Use `schema` SDL element instead of `type schema`.
|
12
|
+
|
3
13
|
### 2.7.0 - 2019-01-29
|
4
14
|
|
5
15
|
Static asset header rules functionality added.
|
data/ext/agoo/agoo.c
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
2
|
|
3
|
+
#include <errno.h>
|
3
4
|
#include <signal.h>
|
4
5
|
#include <stdio.h>
|
6
|
+
#include <string.h>
|
5
7
|
|
6
8
|
#include <ruby.h>
|
7
9
|
|
10
|
+
#include "atomic.h"
|
8
11
|
#include "debug.h"
|
9
12
|
#include "error_stream.h"
|
10
13
|
#include "graphql.h"
|
@@ -21,10 +24,19 @@
|
|
21
24
|
|
22
25
|
extern void graphql_init(VALUE mod);
|
23
26
|
|
27
|
+
sig_atomic_t agoo_stop = 0;
|
28
|
+
|
29
|
+
static atomic_int shutdown_started = AGOO_ATOMIC_INT_INIT(0);
|
30
|
+
|
24
31
|
void
|
25
32
|
agoo_shutdown() {
|
26
|
-
|
27
|
-
|
33
|
+
if (0 == atomic_fetch_add(&shutdown_started, 1)) {
|
34
|
+
rserver_shutdown(Qnil);
|
35
|
+
agoo_log_close();
|
36
|
+
gql_destroy();
|
37
|
+
debug_report();
|
38
|
+
exit(0);
|
39
|
+
}
|
28
40
|
}
|
29
41
|
|
30
42
|
/* Document-method: shutdown
|
@@ -36,8 +48,6 @@ agoo_shutdown() {
|
|
36
48
|
static VALUE
|
37
49
|
ragoo_shutdown(VALUE self) {
|
38
50
|
agoo_shutdown();
|
39
|
-
gql_destroy();
|
40
|
-
debug_report();
|
41
51
|
|
42
52
|
return Qnil;
|
43
53
|
}
|
@@ -79,15 +89,7 @@ ragoo_unsubscribe(VALUE self, VALUE subject) {
|
|
79
89
|
|
80
90
|
static void
|
81
91
|
sig_handler(int sig) {
|
82
|
-
|
83
|
-
rb_gc();
|
84
|
-
#endif
|
85
|
-
agoo_shutdown();
|
86
|
-
gql_destroy();
|
87
|
-
debug_report();
|
88
|
-
// Use exit instead of rb_exit as rb_exit segfaults most of the time.
|
89
|
-
//rb_exit(0);
|
90
|
-
exit(0);
|
92
|
+
agoo_stop = 1;
|
91
93
|
}
|
92
94
|
|
93
95
|
/* Document-module: Agoo
|
@@ -112,12 +114,15 @@ Init_agoo() {
|
|
112
114
|
rb_define_module_function(mod, "publish", ragoo_publish, 2);
|
113
115
|
rb_define_module_function(mod, "unsubscribe", ragoo_unsubscribe, 1);
|
114
116
|
|
115
|
-
signal(SIGINT, sig_handler)
|
116
|
-
|
117
|
-
|
117
|
+
if (SIG_ERR == signal(SIGINT, sig_handler) ||
|
118
|
+
SIG_ERR == signal(SIGTERM, sig_handler) ||
|
119
|
+
SIG_ERR == signal(SIGPIPE, SIG_IGN) ||
|
120
|
+
|
121
|
+
// This causes sleeps and queue pops to return immediately and it can be
|
122
|
+
// called very frequently on mac OS with multiple threads. Something seems
|
123
|
+
// to get stuck.
|
124
|
+
SIG_ERR == signal(SIGVTALRM, SIG_IGN)) {
|
118
125
|
|
119
|
-
|
120
|
-
|
121
|
-
// get stuck.
|
122
|
-
signal(SIGVTALRM, SIG_IGN);
|
126
|
+
rb_raise(rb_eStandardError, "%s", strerror(errno));
|
127
|
+
}
|
123
128
|
}
|
data/ext/agoo/con.c
CHANGED
@@ -88,7 +88,7 @@ agoo_con_destroy(agooCon c) {
|
|
88
88
|
}
|
89
89
|
if (NULL != c->up) {
|
90
90
|
agoo_upgraded_release_con(c->up);
|
91
|
-
|
91
|
+
|
92
92
|
c->up = NULL;
|
93
93
|
}
|
94
94
|
agoo_log_cat(&agoo_con_cat, "Connection %llu closed.", (unsigned long long)c->id);
|
@@ -108,7 +108,7 @@ agoo_con_header_value(const char *header, int hlen, const char *key, int *vlen)
|
|
108
108
|
const char *hend = header + hlen;
|
109
109
|
const char *value;
|
110
110
|
int klen = (int)strlen(key);
|
111
|
-
|
111
|
+
|
112
112
|
while (h < hend) {
|
113
113
|
if (0 == strncmp(key, h, klen) && ':' == h[klen]) {
|
114
114
|
h += klen + 1;
|
@@ -118,7 +118,7 @@ agoo_con_header_value(const char *header, int hlen, const char *key, int *vlen)
|
|
118
118
|
for (; '\r' != *h && '\0' != *h; h++) {
|
119
119
|
}
|
120
120
|
*vlen = (int)(h - value);
|
121
|
-
|
121
|
+
|
122
122
|
return value;
|
123
123
|
}
|
124
124
|
for (; h < hend; h++) {
|
@@ -135,7 +135,7 @@ static HeadReturn
|
|
135
135
|
bad_request(agooCon c, int status, int line) {
|
136
136
|
agooRes res;
|
137
137
|
const char *msg = agoo_http_code_message(status);
|
138
|
-
|
138
|
+
|
139
139
|
if (NULL == (res = agoo_res_create(c))) {
|
140
140
|
agoo_log_cat(&agoo_error_cat, "memory allocation of response failed on connection %llu @ %d.",
|
141
141
|
(unsigned long long)c->id, line);
|
@@ -144,7 +144,7 @@ bad_request(agooCon c, int status, int line) {
|
|
144
144
|
int cnt = snprintf(buf, sizeof(buf),
|
145
145
|
"HTTP/1.1 %d %s\r\nConnection: Close\r\nContent-Length: 0\r\n\r\n", status, msg);
|
146
146
|
agooText message = agoo_text_create(buf, cnt);
|
147
|
-
|
147
|
+
|
148
148
|
if (NULL == c->res_tail) {
|
149
149
|
c->res_head = res;
|
150
150
|
} else {
|
@@ -161,7 +161,7 @@ static bool
|
|
161
161
|
should_close(const char *header, int hlen) {
|
162
162
|
const char *v;
|
163
163
|
int vlen = 0;
|
164
|
-
|
164
|
+
|
165
165
|
if (NULL != (v = agoo_con_header_value(header, hlen, "Connection", &vlen))) {
|
166
166
|
return (5 == vlen && 0 == strncasecmp("Close", v, 5));
|
167
167
|
}
|
@@ -172,7 +172,7 @@ static bool
|
|
172
172
|
page_response(agooCon c, agooPage p, char *hend) {
|
173
173
|
agooRes res;
|
174
174
|
char *b;
|
175
|
-
|
175
|
+
|
176
176
|
if (NULL == (res = agoo_res_create(c))) {
|
177
177
|
return true;
|
178
178
|
}
|
@@ -253,7 +253,7 @@ agoo_con_header_read(agooCon c, size_t *mlenp) {
|
|
253
253
|
const char *v;
|
254
254
|
int vlen = 0;
|
255
255
|
char *vend;
|
256
|
-
|
256
|
+
|
257
257
|
if (3 == b - c->buf && 0 == strncmp("PUT", c->buf, 3)) {
|
258
258
|
method = AGOO_PUT;
|
259
259
|
} else if (4 == b - c->buf && 0 == strncmp("POST", c->buf, 4)) {
|
@@ -345,7 +345,7 @@ agoo_con_header_read(agooCon c, size_t *mlenp) {
|
|
345
345
|
return bad_request(c, 500, __LINE__);
|
346
346
|
}
|
347
347
|
return HEAD_HANDLED;
|
348
|
-
}
|
348
|
+
}
|
349
349
|
if (NULL == agoo_server.hook404) {
|
350
350
|
return bad_request(c, 404, __LINE__);
|
351
351
|
}
|
@@ -445,7 +445,7 @@ agoo_con_http_read(agooCon c) {
|
|
445
445
|
|
446
446
|
switch (agoo_con_header_read(c, &mlen)) {
|
447
447
|
case HEAD_AGAIN:
|
448
|
-
// Try again the next time. Didn't read enough..
|
448
|
+
// Try again the next time. Didn't read enough..
|
449
449
|
return false;
|
450
450
|
case HEAD_OK:
|
451
451
|
// req was created
|
@@ -528,7 +528,7 @@ con_ws_read(agooCon c) {
|
|
528
528
|
ssize_t cnt;
|
529
529
|
uint8_t *b;
|
530
530
|
uint8_t op;
|
531
|
-
long mlen;
|
531
|
+
long mlen;
|
532
532
|
|
533
533
|
if (NULL != c->req) {
|
534
534
|
cnt = recv(c->sock, c->req->msg + c->bcnt, c->req->mlen - c->bcnt, 0);
|
@@ -667,7 +667,7 @@ agoo_con_http_write(agooCon c) {
|
|
667
667
|
if (c->wcnt == message->len) { // finished
|
668
668
|
agooRes res = c->res_head;
|
669
669
|
bool done = res->close;
|
670
|
-
|
670
|
+
|
671
671
|
c->res_head = res->next;
|
672
672
|
if (res == c->res_tail) {
|
673
673
|
c->res_tail = NULL;
|
@@ -700,11 +700,11 @@ con_ws_write(agooCon c) {
|
|
700
700
|
}
|
701
701
|
len = snprintf(msg, sizeof(msg) - 1, "Socket error @ %llu.", (unsigned long long)c->id);
|
702
702
|
push_error(c->up, msg, len);
|
703
|
-
|
703
|
+
|
704
704
|
agoo_log_cat(&agoo_error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
|
705
705
|
agoo_ws_req_close(c);
|
706
706
|
agoo_res_destroy(res);
|
707
|
-
|
707
|
+
|
708
708
|
return false;
|
709
709
|
}
|
710
710
|
} else if (res->pong) {
|
@@ -720,7 +720,7 @@ con_ws_write(agooCon c) {
|
|
720
720
|
agoo_log_cat(&agoo_error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
|
721
721
|
agoo_ws_req_close(c);
|
722
722
|
agoo_res_destroy(res);
|
723
|
-
|
723
|
+
|
724
724
|
return false;
|
725
725
|
}
|
726
726
|
} else {
|
@@ -742,7 +742,7 @@ con_ws_write(agooCon c) {
|
|
742
742
|
c->timeout = dtime() + CON_TIMEOUT;
|
743
743
|
if (0 == c->wcnt) {
|
744
744
|
agooText t;
|
745
|
-
|
745
|
+
|
746
746
|
if (agoo_push_cat.on) {
|
747
747
|
if (message->bin) {
|
748
748
|
agoo_log_cat(&agoo_push_cat, "%llu binary", (unsigned long long)c->id);
|
@@ -767,14 +767,14 @@ con_ws_write(agooCon c) {
|
|
767
767
|
push_error(c->up, msg, len);
|
768
768
|
agoo_log_cat(&agoo_error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
|
769
769
|
agoo_ws_req_close(c);
|
770
|
-
|
770
|
+
|
771
771
|
return false;
|
772
772
|
}
|
773
773
|
c->wcnt += cnt;
|
774
774
|
if (c->wcnt == message->len) { // finished
|
775
775
|
agooRes res = c->res_head;
|
776
776
|
bool done = res->close;
|
777
|
-
|
777
|
+
|
778
778
|
c->res_head = res->next;
|
779
779
|
if (res == c->res_tail) {
|
780
780
|
c->res_tail = NULL;
|
@@ -801,7 +801,7 @@ con_sse_write(agooCon c) {
|
|
801
801
|
c->timeout = dtime() + CON_TIMEOUT *2;
|
802
802
|
if (0 == c->wcnt) {
|
803
803
|
agooText t;
|
804
|
-
|
804
|
+
|
805
805
|
if (agoo_push_cat.on) {
|
806
806
|
agoo_log_cat(&agoo_push_cat, "%llu: %s %p", (unsigned long long)c->id, message->text, (void*)res);
|
807
807
|
}
|
@@ -821,14 +821,14 @@ con_sse_write(agooCon c) {
|
|
821
821
|
len = snprintf(msg, sizeof(msg) - 1, "Socket error @ %llu.", (unsigned long long)c->id);
|
822
822
|
push_error(c->up, msg, len);
|
823
823
|
agoo_log_cat(&agoo_error_cat, "Socket error @ %llu.", (unsigned long long)c->id);
|
824
|
-
|
824
|
+
|
825
825
|
return false;
|
826
826
|
}
|
827
827
|
c->wcnt += cnt;
|
828
828
|
if (c->wcnt == message->len) { // finished
|
829
829
|
agooRes res = c->res_head;
|
830
830
|
bool done = res->close;
|
831
|
-
|
831
|
+
|
832
832
|
c->res_head = res->next;
|
833
833
|
if (res == c->res_tail) {
|
834
834
|
c->res_tail = NULL;
|
@@ -885,12 +885,12 @@ process_pub_con(agooPub pub, agooConLoop loop) {
|
|
885
885
|
|
886
886
|
if (NULL != up && NULL != up->con && up->con->loop == loop) {
|
887
887
|
int pending;
|
888
|
-
|
888
|
+
|
889
889
|
// TBD Change pending to be based on length of con queue
|
890
890
|
if (1 == (pending = atomic_fetch_sub(&up->pending, 1))) {
|
891
891
|
if (NULL != up && agoo_server.ctx_nil_value != up->ctx && up->on_empty) {
|
892
892
|
agooReq req = agoo_req_create(0);
|
893
|
-
|
893
|
+
|
894
894
|
req->up = up;
|
895
895
|
req->method = AGOO_ON_EMPTY;
|
896
896
|
req->hook = agoo_hook_create(AGOO_NONE, NULL, up->ctx, PUSH_HOOK, &agoo_server.eval_queue);
|
@@ -961,7 +961,7 @@ process_pub_con(agooPub pub, agooConLoop loop) {
|
|
961
961
|
short
|
962
962
|
agoo_con_http_events(agooCon c) {
|
963
963
|
short events = 0;
|
964
|
-
|
964
|
+
|
965
965
|
if (NULL != c->res_head && NULL != agoo_res_message(c->res_head)) {
|
966
966
|
events = POLLIN | POLLOUT;
|
967
967
|
} else if (!c->closing) {
|
@@ -1029,7 +1029,7 @@ con_ready_check(void *ctx, double now) {
|
|
1029
1029
|
agooCon c = (agooCon)ctx;
|
1030
1030
|
|
1031
1031
|
if (c->dead || 0 == c->sock) {
|
1032
|
-
if (remove_dead_res(c)) {
|
1032
|
+
if (remove_dead_res(c)) {
|
1033
1033
|
return false;
|
1034
1034
|
}
|
1035
1035
|
} else if (0.0 == c->timeout || now < c->timeout) {
|
@@ -1106,7 +1106,7 @@ static struct _agooHandler con_handler = {
|
|
1106
1106
|
.read = con_ready_read,
|
1107
1107
|
.write = con_ready_write,
|
1108
1108
|
.error = NULL,
|
1109
|
-
.destroy = con_ready_destroy,
|
1109
|
+
.destroy = con_ready_destroy,
|
1110
1110
|
};
|
1111
1111
|
|
1112
1112
|
static agooReadyIO
|
@@ -1119,7 +1119,7 @@ con_queue_ready_read(agooReady ready, void *ctx) {
|
|
1119
1119
|
agooConLoop loop = (agooConLoop)ctx;
|
1120
1120
|
struct _agooErr err = AGOO_ERR_INIT;
|
1121
1121
|
agooCon c;
|
1122
|
-
|
1122
|
+
|
1123
1123
|
agoo_queue_release(&agoo_server.con_queue);
|
1124
1124
|
while (NULL != (c = (agooCon)agoo_queue_pop(&agoo_server.con_queue, 0.0))) {
|
1125
1125
|
c->loop = loop;
|
@@ -1136,8 +1136,8 @@ static struct _agooHandler con_queue_handler = {
|
|
1136
1136
|
.check = NULL,
|
1137
1137
|
.read = con_queue_ready_read,
|
1138
1138
|
.write = NULL,
|
1139
|
-
.error = NULL,
|
1140
|
-
.destroy = NULL,
|
1139
|
+
.error = NULL,
|
1140
|
+
.destroy = NULL,
|
1141
1141
|
};
|
1142
1142
|
|
1143
1143
|
static bool
|
@@ -1157,8 +1157,8 @@ static struct _agooHandler pub_queue_handler = {
|
|
1157
1157
|
.check = NULL,
|
1158
1158
|
.read = pub_queue_ready_read,
|
1159
1159
|
.write = NULL,
|
1160
|
-
.error = NULL,
|
1161
|
-
.destroy = NULL,
|
1160
|
+
.error = NULL,
|
1161
|
+
.destroy = NULL,
|
1162
1162
|
};
|
1163
1163
|
|
1164
1164
|
void*
|
@@ -1170,7 +1170,7 @@ agoo_con_loop(void *x) {
|
|
1170
1170
|
agooCon c;
|
1171
1171
|
int con_queue_fd = agoo_queue_listen(&agoo_server.con_queue);
|
1172
1172
|
int pub_queue_fd = agoo_queue_listen(&loop->pub_queue);
|
1173
|
-
|
1173
|
+
|
1174
1174
|
if (NULL == ready) {
|
1175
1175
|
agoo_log_cat(&agoo_error_cat, "Failed to create connection manager. %s", err.msg);
|
1176
1176
|
exit(EXIT_FAILURE);
|
@@ -1184,7 +1184,7 @@ agoo_con_loop(void *x) {
|
|
1184
1184
|
return NULL;
|
1185
1185
|
}
|
1186
1186
|
atomic_fetch_add(&agoo_server.running, 1);
|
1187
|
-
|
1187
|
+
|
1188
1188
|
while (agoo_server.active) {
|
1189
1189
|
while (NULL != (c = (agooCon)agoo_queue_pop(&agoo_server.con_queue, 0.0))) {
|
1190
1190
|
c->loop = loop;
|
@@ -1215,7 +1215,7 @@ agoo_conloop_create(agooErr err, int id) {
|
|
1215
1215
|
AGOO_ERR_MEM(err, "connection thread");
|
1216
1216
|
} else {
|
1217
1217
|
int stat;
|
1218
|
-
|
1218
|
+
|
1219
1219
|
loop->next = NULL;
|
1220
1220
|
if (AGOO_ERR_OK != agoo_queue_multi_init(err, &loop->pub_queue, 256, true, false)) {
|
1221
1221
|
AGOO_FREE(loop);
|
@@ -1240,7 +1240,7 @@ agoo_conloop_create(agooErr err, int id) {
|
|
1240
1240
|
void
|
1241
1241
|
agoo_conloop_destroy(agooConLoop loop) {
|
1242
1242
|
agooRes res;
|
1243
|
-
|
1243
|
+
|
1244
1244
|
agoo_queue_cleanup(&loop->pub_queue);
|
1245
1245
|
while (NULL != (res = loop->res_head)) {
|
1246
1246
|
loop->res_head = res->next;
|
data/ext/agoo/error_stream.c
CHANGED
@@ -25,13 +25,12 @@ error_stream_new() {
|
|
25
25
|
ErrorStream es = (ErrorStream)AGOO_MALLOC(sizeof(struct _errorStream));
|
26
26
|
|
27
27
|
if (NULL == es) {
|
28
|
-
|
29
|
-
// specs. Better not to break everything if this fails.
|
30
|
-
return Qnil;
|
28
|
+
rb_raise(rb_eNoMemError, "Failed to allocate memory for the error stream.");
|
31
29
|
}
|
32
30
|
es->server = NULL;
|
33
|
-
es->text = agoo_text_allocate(1024)
|
34
|
-
|
31
|
+
if (NULL == (es->text = agoo_text_allocate(1024))) {
|
32
|
+
rb_raise(rb_eNoMemError, "Failed to allocate memory for the error stream.");
|
33
|
+
}
|
35
34
|
return Data_Wrap_Struct(es_class, NULL, es_free, es);
|
36
35
|
}
|
37
36
|
|
@@ -48,7 +47,9 @@ es_puts(VALUE self, VALUE str) {
|
|
48
47
|
|
49
48
|
es->text = agoo_text_append(es->text, StringValuePtr(str), (int)RSTRING_LEN(str));
|
50
49
|
es->text = agoo_text_append(es->text, "\n", 1);
|
51
|
-
|
50
|
+
if (NULL == es->text) {
|
51
|
+
rb_raise(rb_eNoMemError, "Failed to allocate memory for the error stream puts.");
|
52
|
+
}
|
52
53
|
return Qnil;
|
53
54
|
}
|
54
55
|
|
@@ -62,9 +63,10 @@ static VALUE
|
|
62
63
|
es_write(VALUE self, VALUE str) {
|
63
64
|
ErrorStream es = (ErrorStream)DATA_PTR(self);
|
64
65
|
int cnt = (int)RSTRING_LEN(str);
|
65
|
-
|
66
|
-
es->text = agoo_text_append(es->text, StringValuePtr(str), cnt);
|
67
66
|
|
67
|
+
if (NULL == (es->text = agoo_text_append(es->text, StringValuePtr(str), cnt))) {
|
68
|
+
rb_raise(rb_eNoMemError, "Failed to allocate memory for the error stream puts.");
|
69
|
+
}
|
68
70
|
return INT2NUM(cnt);
|
69
71
|
}
|
70
72
|
|
data/ext/agoo/gqlcobj.c
CHANGED
@@ -7,6 +7,31 @@
|
|
7
7
|
#include "debug.h"
|
8
8
|
#include "gqlcobj.h"
|
9
9
|
#include "gqleval.h"
|
10
|
+
#include "gqlvalue.h"
|
11
|
+
#include "graphql.h"
|
10
12
|
|
11
13
|
|
14
|
+
gqlType
|
15
|
+
gql_cobj_ref_type(gqlRef ref) {
|
16
|
+
gqlCobj obj = (gqlCobj)ref;
|
17
|
+
|
18
|
+
if (NULL != obj && NULL != obj->clas) {
|
19
|
+
return gql_type_get(obj->clas->name);
|
20
|
+
}
|
21
|
+
return NULL;
|
22
|
+
}
|
23
|
+
|
24
|
+
int
|
25
|
+
gql_cobj_resolve(agooErr err, gqlDoc doc, gqlRef target, gqlField field, gqlSel sel, gqlValue result, int depth) {
|
26
|
+
gqlCobj obj = (gqlCobj)target;
|
27
|
+
gqlCmethod method;
|
28
|
+
|
29
|
+
for (method = obj->clas->methods; NULL != method->key; method++) {
|
30
|
+
if (0 == strcmp(method->key, sel->name)) {
|
31
|
+
return method->func(err, doc, obj, field, sel, result, depth);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
return agoo_err_set(err, AGOO_ERR_EVAL, "%s is not a field on %s.", sel->name, obj->clas->name);
|
35
|
+
}
|
36
|
+
|
12
37
|
// TBD when a type is created, add a cobj to it
|