agoo 2.5.7 → 2.6.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.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +38 -0
- data/ext/agoo/agoo.c +11 -2
- data/ext/agoo/bind.c +15 -20
- data/ext/agoo/con.c +32 -25
- data/ext/agoo/debug.c +225 -162
- data/ext/agoo/debug.h +31 -51
- data/ext/agoo/doc.c +278 -5
- data/ext/agoo/doc.h +6 -1
- data/ext/agoo/err.c +1 -0
- data/ext/agoo/err.h +1 -0
- data/ext/agoo/error_stream.c +3 -6
- data/ext/agoo/gqlcobj.c +12 -0
- data/ext/agoo/gqlcobj.h +25 -0
- data/ext/agoo/gqleval.c +520 -0
- data/ext/agoo/gqleval.h +49 -0
- data/ext/agoo/gqlintro.c +1237 -97
- data/ext/agoo/gqlintro.h +8 -0
- data/ext/agoo/gqljson.c +460 -0
- data/ext/agoo/gqljson.h +15 -0
- data/ext/agoo/gqlvalue.c +679 -136
- data/ext/agoo/gqlvalue.h +29 -7
- data/ext/agoo/graphql.c +841 -362
- data/ext/agoo/graphql.h +180 -90
- data/ext/agoo/hook.c +8 -16
- data/ext/agoo/http.c +3 -4
- data/ext/agoo/log.c +22 -25
- data/ext/agoo/log.h +1 -0
- data/ext/agoo/page.c +24 -40
- data/ext/agoo/pub.c +23 -21
- data/ext/agoo/queue.c +2 -4
- data/ext/agoo/ready.c +9 -9
- data/ext/agoo/req.c +80 -5
- data/ext/agoo/req.h +2 -0
- data/ext/agoo/res.c +1 -3
- data/ext/agoo/rgraphql.c +753 -0
- data/ext/agoo/rresponse.c +9 -15
- data/ext/agoo/rserver.c +18 -17
- data/ext/agoo/sdl.c +1264 -120
- data/ext/agoo/sdl.h +8 -1
- data/ext/agoo/sectime.c +136 -0
- data/ext/agoo/sectime.h +19 -0
- data/ext/agoo/server.c +1 -3
- data/ext/agoo/subject.c +2 -4
- data/ext/agoo/text.c +124 -18
- data/ext/agoo/text.h +5 -1
- data/ext/agoo/upgraded.c +2 -4
- data/lib/agoo/version.rb +1 -1
- data/test/base_handler_test.rb +43 -40
- data/test/bind_test.rb +49 -48
- data/test/graphql_test.rb +1019 -0
- data/test/hijack_test.rb +1 -1
- data/test/rack_handler_test.rb +40 -34
- data/test/static_test.rb +33 -32
- metadata +17 -6
data/ext/agoo/gqljson.h
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
|
+
|
3
|
+
#ifndef AGOO_GQLJSON_H
|
4
|
+
#define AGOO_GQLJSON_H
|
5
|
+
|
6
|
+
|
7
|
+
#include <stdlib.h>
|
8
|
+
|
9
|
+
#include "err.h"
|
10
|
+
|
11
|
+
struct _gqlValue;
|
12
|
+
|
13
|
+
extern struct _gqlValue* gql_json_parse(agooErr err, const char *json, size_t len);
|
14
|
+
|
15
|
+
#endif // AGOO_GQLJSON_H
|
data/ext/agoo/gqlvalue.c
CHANGED
@@ -8,10 +8,11 @@
|
|
8
8
|
#include "debug.h"
|
9
9
|
#include "gqlvalue.h"
|
10
10
|
#include "graphql.h"
|
11
|
+
#include "sectime.h"
|
11
12
|
|
12
13
|
static const char spaces[256] = "\n ";
|
13
14
|
|
14
|
-
//
|
15
|
+
// Null type
|
15
16
|
static agooText
|
16
17
|
null_to_text(agooText text, gqlValue value, int indent, int depth) {
|
17
18
|
return agoo_text_append(text, "null", 4);
|
@@ -21,11 +22,11 @@ struct _gqlType gql_null_type = {
|
|
21
22
|
.name = "Null",
|
22
23
|
.desc = "Null scalar.",
|
23
24
|
.kind = GQL_SCALAR,
|
24
|
-
.
|
25
|
+
.scalar_kind = GQL_SCALAR_NULL,
|
25
26
|
.core = true,
|
26
|
-
.coerce = NULL,
|
27
27
|
.destroy = NULL,
|
28
28
|
.to_json = null_to_text,
|
29
|
+
.to_sdl = null_to_text,
|
29
30
|
};
|
30
31
|
|
31
32
|
// Int type
|
@@ -43,11 +44,11 @@ struct _gqlType gql_int_type = {
|
|
43
44
|
.name = "Int",
|
44
45
|
.desc = "Int scalar.",
|
45
46
|
.kind = GQL_SCALAR,
|
46
|
-
.
|
47
|
+
.scalar_kind = GQL_SCALAR_INT,
|
47
48
|
.core = true,
|
48
|
-
.coerce = NULL,
|
49
49
|
.destroy = NULL,
|
50
50
|
.to_json = int_to_text,
|
51
|
+
.to_sdl = int_to_text,
|
51
52
|
};
|
52
53
|
|
53
54
|
// I64 type, add on type.
|
@@ -65,60 +66,98 @@ struct _gqlType gql_i64_type = {
|
|
65
66
|
.name = "I64",
|
66
67
|
.desc = "64 bit integer scalar.",
|
67
68
|
.kind = GQL_SCALAR,
|
68
|
-
.
|
69
|
+
.scalar_kind = GQL_SCALAR_I64,
|
69
70
|
.core = true,
|
70
|
-
.coerce = NULL,
|
71
71
|
.destroy = NULL,
|
72
72
|
.to_json = i64_to_text,
|
73
|
+
.to_sdl = i64_to_text,
|
73
74
|
};
|
74
75
|
|
75
76
|
// String type
|
76
77
|
static void
|
77
78
|
string_destroy(gqlValue value) {
|
78
|
-
|
79
|
+
if (value->str.alloced) {
|
80
|
+
AGOO_FREE((char*)value->str.ptr);
|
81
|
+
}
|
79
82
|
}
|
80
83
|
|
81
|
-
static agooText
|
84
|
+
static agooText
|
85
|
+
string_to_text(agooText text, gqlValue value, int indent, int depth) {
|
86
|
+
if (!value->str.alloced) {
|
87
|
+
text = agoo_text_append(text, "\"", 1);
|
88
|
+
text = agoo_text_append_json(text, value->str.a, -1);
|
89
|
+
text = agoo_text_append(text, "\"", 1);
|
90
|
+
} else if (NULL == value->str.ptr) {
|
91
|
+
text = agoo_text_append(text, "null", 4);
|
92
|
+
} else {
|
93
|
+
text = agoo_text_append(text, "\"", 1);
|
94
|
+
text = agoo_text_append_json(text, value->str.ptr, -1);
|
95
|
+
text = agoo_text_append(text, "\"", 1);
|
96
|
+
}
|
97
|
+
return text;
|
98
|
+
}
|
82
99
|
|
83
100
|
struct _gqlType gql_string_type = {
|
84
101
|
.name = "String",
|
85
102
|
.desc = "String scalar.",
|
86
103
|
.kind = GQL_SCALAR,
|
87
|
-
.
|
104
|
+
.scalar_kind = GQL_SCALAR_STRING,
|
88
105
|
.core = true,
|
89
|
-
.coerce = NULL,
|
90
106
|
.destroy = string_destroy,
|
91
107
|
.to_json = string_to_text,
|
108
|
+
.to_sdl = string_to_text,
|
92
109
|
};
|
93
110
|
|
94
|
-
//
|
95
|
-
|
96
|
-
|
97
|
-
.
|
111
|
+
// Token type
|
112
|
+
static agooText
|
113
|
+
token_to_text(agooText text, gqlValue value, int indent, int depth) {
|
114
|
+
if (!value->str.alloced) {
|
115
|
+
text = agoo_text_append_json(text, value->str.a, -1);
|
116
|
+
} else if (NULL == value->str.ptr) {
|
117
|
+
text = agoo_text_append(text, "null", 4);
|
118
|
+
} else {
|
119
|
+
text = agoo_text_append_json(text, value->str.ptr, -1);
|
120
|
+
}
|
121
|
+
return text;
|
122
|
+
}
|
123
|
+
|
124
|
+
struct _gqlType gql_token_type = {
|
125
|
+
.name = "Token",
|
126
|
+
.desc = "Token scalar.",
|
98
127
|
.kind = GQL_SCALAR,
|
99
|
-
.
|
128
|
+
.scalar_kind = GQL_SCALAR_TOKEN,
|
100
129
|
.core = true,
|
101
|
-
.
|
102
|
-
.destroy = NULL,
|
130
|
+
.destroy = string_destroy,
|
103
131
|
.to_json = string_to_text,
|
132
|
+
.to_sdl = token_to_text,
|
104
133
|
};
|
105
134
|
|
135
|
+
// Variable type ($var)
|
106
136
|
static agooText
|
107
|
-
|
108
|
-
if (
|
109
|
-
text =
|
110
|
-
text =
|
111
|
-
|
112
|
-
} else if (NULL == value->str) {
|
137
|
+
var_to_text(agooText text, gqlValue value, int indent, int depth) {
|
138
|
+
if (!value->str.alloced) {
|
139
|
+
text = agoo_text_append_char(text, '%');
|
140
|
+
text = agoo_text_append_json(text, value->str.a, -1);
|
141
|
+
} else if (NULL == value->str.ptr) {
|
113
142
|
text = agoo_text_append(text, "null", 4);
|
114
143
|
} else {
|
115
|
-
text =
|
116
|
-
text =
|
117
|
-
text = agoo_text_append(text, "\"", 1);
|
144
|
+
text = agoo_text_append_char(text, '%');
|
145
|
+
text = agoo_text_append_json(text, value->str.ptr, -1);
|
118
146
|
}
|
119
147
|
return text;
|
120
148
|
}
|
121
149
|
|
150
|
+
struct _gqlType gql_var_type = {
|
151
|
+
.name = "Var",
|
152
|
+
.desc = "Variable scalar.",
|
153
|
+
.kind = GQL_SCALAR,
|
154
|
+
.scalar_kind = GQL_SCALAR_VAR,
|
155
|
+
.core = true,
|
156
|
+
.destroy = string_destroy,
|
157
|
+
.to_json = var_to_text,
|
158
|
+
.to_sdl = var_to_text,
|
159
|
+
};
|
160
|
+
|
122
161
|
// Bool type
|
123
162
|
static agooText
|
124
163
|
bool_to_text(agooText text, gqlValue value, int indent, int depth) {
|
@@ -134,11 +173,11 @@ struct _gqlType gql_bool_type = {
|
|
134
173
|
.name = "Boolean",
|
135
174
|
.desc = "Boolean scalar.",
|
136
175
|
.kind = GQL_SCALAR,
|
137
|
-
.
|
176
|
+
.scalar_kind = GQL_SCALAR_BOOL,
|
138
177
|
.core = true,
|
139
|
-
.coerce = NULL,
|
140
178
|
.destroy = NULL,
|
141
179
|
.to_json = bool_to_text,
|
180
|
+
.to_sdl = bool_to_text,
|
142
181
|
};
|
143
182
|
|
144
183
|
// Float type
|
@@ -156,11 +195,11 @@ struct _gqlType gql_float_type = {
|
|
156
195
|
.name = "Float",
|
157
196
|
.desc = "Float scalar.",
|
158
197
|
.kind = GQL_SCALAR,
|
159
|
-
.
|
198
|
+
.scalar_kind = GQL_SCALAR_FLOAT,
|
160
199
|
.core = true,
|
161
|
-
.coerce = NULL,
|
162
200
|
.destroy = NULL,
|
163
201
|
.to_json = float_to_text,
|
202
|
+
.to_sdl = float_to_text,
|
164
203
|
};
|
165
204
|
|
166
205
|
// Time type
|
@@ -412,20 +451,18 @@ time_parse(agooErr err, const char *str, int len) {
|
|
412
451
|
|
413
452
|
static agooText
|
414
453
|
time_to_text(agooText text, gqlValue value, int indent, int depth) {
|
415
|
-
char
|
416
|
-
int
|
417
|
-
struct
|
418
|
-
int64_t
|
419
|
-
time_t
|
420
|
-
long
|
454
|
+
char str[64];
|
455
|
+
int cnt;
|
456
|
+
struct _agooTime at;
|
457
|
+
int64_t tt = value->time;
|
458
|
+
time_t t = (time_t)(tt / 1000000000LL);
|
459
|
+
long nsecs = tt - (int64_t)t * 1000000000LL;
|
421
460
|
|
422
461
|
if (0 > nsecs) {
|
423
462
|
nsecs = -nsecs;
|
424
463
|
}
|
425
|
-
|
426
|
-
cnt = sprintf(str, "\"%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ\"",
|
427
|
-
1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
|
428
|
-
tm.tm_hour, tm.tm_min, tm.tm_sec, (long)nsecs);
|
464
|
+
agoo_sectime(t, &at);
|
465
|
+
cnt = sprintf(str, "\"%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ\"", at.year, at.mon, at.day, at.hour, at.min, at.sec, (long)nsecs);
|
429
466
|
|
430
467
|
return agoo_text_append(text, str, cnt);
|
431
468
|
}
|
@@ -434,11 +471,11 @@ struct _gqlType gql_time_type = {
|
|
434
471
|
.name = "Time",
|
435
472
|
.desc = "Time zulu scalar.",
|
436
473
|
.kind = GQL_SCALAR,
|
437
|
-
.
|
474
|
+
.scalar_kind = GQL_SCALAR_TIME,
|
438
475
|
.core = true,
|
439
|
-
.coerce = NULL,
|
440
476
|
.destroy = NULL,
|
441
477
|
.to_json = time_to_text,
|
478
|
+
.to_sdl = time_to_text,
|
442
479
|
};
|
443
480
|
|
444
481
|
// Uuid type
|
@@ -527,40 +564,11 @@ struct _gqlType gql_uuid_type = {
|
|
527
564
|
.name = "Uuid",
|
528
565
|
.desc = "UUID scalar.",
|
529
566
|
.kind = GQL_SCALAR,
|
530
|
-
.
|
567
|
+
.scalar_kind = GQL_SCALAR_UUID,
|
531
568
|
.core = true,
|
532
|
-
.coerce = NULL,
|
533
569
|
.destroy = NULL,
|
534
570
|
.to_json = uuid_to_text,
|
535
|
-
|
536
|
-
|
537
|
-
// Url type
|
538
|
-
static void
|
539
|
-
url_destroy(gqlValue value) {
|
540
|
-
free((char*)value->url);
|
541
|
-
}
|
542
|
-
|
543
|
-
static agooText
|
544
|
-
url_to_text(agooText text, gqlValue value, int indent, int depth) {
|
545
|
-
if (NULL == value->url) {
|
546
|
-
return agoo_text_append(text, "null", 4);
|
547
|
-
}
|
548
|
-
text = agoo_text_append(text, "\"", 1);
|
549
|
-
text = agoo_text_append(text, value->url, -1);
|
550
|
-
text = agoo_text_append(text, "\"", 1);
|
551
|
-
|
552
|
-
return text;
|
553
|
-
}
|
554
|
-
|
555
|
-
struct _gqlType gql_url_type = {
|
556
|
-
.name = "Url",
|
557
|
-
.desc = "URL scalar.",
|
558
|
-
.kind = GQL_SCALAR,
|
559
|
-
.locked = true,
|
560
|
-
.core = true,
|
561
|
-
.coerce = NULL,
|
562
|
-
.destroy = url_destroy,
|
563
|
-
.to_json = url_to_text,
|
571
|
+
.to_sdl = uuid_to_text,
|
564
572
|
};
|
565
573
|
|
566
574
|
// List, not visible but used for list values.
|
@@ -571,8 +579,7 @@ list_destroy(gqlValue value) {
|
|
571
579
|
while (NULL != (link = value->members)) {
|
572
580
|
value->members = link->next;
|
573
581
|
gql_value_destroy(link->value);
|
574
|
-
|
575
|
-
free(link);
|
582
|
+
AGOO_FREE(link);
|
576
583
|
}
|
577
584
|
}
|
578
585
|
|
@@ -582,7 +589,40 @@ list_to_json(agooText text, gqlValue value, int indent, int depth) {
|
|
582
589
|
int i2 = i + indent;
|
583
590
|
int d2 = depth + 1;
|
584
591
|
gqlLink link;
|
585
|
-
|
592
|
+
|
593
|
+
if (0 < indent) {
|
594
|
+
i++; // for \n
|
595
|
+
i2++;
|
596
|
+
}
|
597
|
+
if ((int)sizeof(spaces) <= i) {
|
598
|
+
i2 = sizeof(spaces) - 1;
|
599
|
+
i = i2 - indent;
|
600
|
+
}
|
601
|
+
text = agoo_text_append(text, "[", 1);
|
602
|
+
for (link = value->members; NULL != link; link = link->next) {
|
603
|
+
if (0 < i2) {
|
604
|
+
text = agoo_text_append(text, spaces, i2);
|
605
|
+
}
|
606
|
+
text = gql_value_json(text, link->value, indent, d2);
|
607
|
+
if (NULL != link->next) {
|
608
|
+
text = agoo_text_append(text, ",", 1);
|
609
|
+
}
|
610
|
+
}
|
611
|
+
if (0 < indent) {
|
612
|
+
text = agoo_text_append(text, spaces, i);
|
613
|
+
}
|
614
|
+
text = agoo_text_append(text, "]", 1);
|
615
|
+
|
616
|
+
return text;
|
617
|
+
}
|
618
|
+
|
619
|
+
static agooText
|
620
|
+
list_to_sdl(agooText text, gqlValue value, int indent, int depth) {
|
621
|
+
int i = indent * depth;
|
622
|
+
int i2 = i + indent;
|
623
|
+
int d2 = depth + 1;
|
624
|
+
gqlLink link;
|
625
|
+
|
586
626
|
if (0 < indent) {
|
587
627
|
i++; // for \n
|
588
628
|
i2++;
|
@@ -593,8 +633,10 @@ list_to_json(agooText text, gqlValue value, int indent, int depth) {
|
|
593
633
|
}
|
594
634
|
text = agoo_text_append(text, "[", 1);
|
595
635
|
for (link = value->members; NULL != link; link = link->next) {
|
596
|
-
|
597
|
-
|
636
|
+
if (0 < i2) {
|
637
|
+
text = agoo_text_append(text, spaces, i2);
|
638
|
+
}
|
639
|
+
text = link->value->type->to_sdl(text, link->value, indent, d2);
|
598
640
|
if (NULL != link->next) {
|
599
641
|
text = agoo_text_append(text, ",", 1);
|
600
642
|
}
|
@@ -611,11 +653,11 @@ struct _gqlType list_type = { // unregistered
|
|
611
653
|
.name = "__List",
|
612
654
|
.desc = NULL,
|
613
655
|
.kind = GQL_SCALAR,
|
614
|
-
.
|
656
|
+
.scalar_kind = GQL_SCALAR_LIST,
|
615
657
|
.core = true,
|
616
|
-
.coerce = NULL,
|
617
658
|
.destroy = list_destroy,
|
618
659
|
.to_json = list_to_json,
|
660
|
+
.to_sdl = list_to_sdl,
|
619
661
|
};
|
620
662
|
|
621
663
|
// Object, not visible but used for object values.
|
@@ -626,14 +668,13 @@ object_destroy(gqlValue value) {
|
|
626
668
|
while (NULL != (link = value->members)) {
|
627
669
|
value->members = link->next;
|
628
670
|
gql_value_destroy(link->value);
|
629
|
-
|
630
|
-
|
631
|
-
free(link);
|
671
|
+
AGOO_FREE(link->key);
|
672
|
+
AGOO_FREE(link);
|
632
673
|
}
|
633
674
|
}
|
634
675
|
|
635
|
-
|
636
|
-
|
676
|
+
agooText
|
677
|
+
gql_object_to_json(agooText text, gqlValue value, int indent, int depth) {
|
637
678
|
int i = indent * depth;
|
638
679
|
int i2 = i + indent;
|
639
680
|
int d2 = depth + 1;
|
@@ -649,15 +690,56 @@ object_to_json(agooText text, gqlValue value, int indent, int depth) {
|
|
649
690
|
}
|
650
691
|
text = agoo_text_append(text, "{", 1);
|
651
692
|
for (link = value->members; NULL != link; link = link->next) {
|
652
|
-
|
693
|
+
if (0 < i2) {
|
694
|
+
text = agoo_text_append(text, spaces, i2);
|
695
|
+
}
|
653
696
|
text = agoo_text_append(text, "\"", 1);
|
654
697
|
text = agoo_text_append(text, link->key, -1);
|
655
698
|
if (0 < indent) {
|
656
|
-
text = agoo_text_append(text, "\":
|
699
|
+
text = agoo_text_append(text, "\":", 2);
|
657
700
|
} else {
|
658
701
|
text = agoo_text_append(text, "\":", 2);
|
659
702
|
}
|
660
|
-
text =
|
703
|
+
text = gql_value_json(text, link->value, indent, d2);
|
704
|
+
if (NULL != link->next) {
|
705
|
+
text = agoo_text_append(text, ",", 1);
|
706
|
+
}
|
707
|
+
}
|
708
|
+
if (0 < indent) {
|
709
|
+
text = agoo_text_append(text, spaces, i);
|
710
|
+
}
|
711
|
+
text = agoo_text_append(text, "}", 1);
|
712
|
+
|
713
|
+
return text;
|
714
|
+
}
|
715
|
+
|
716
|
+
agooText
|
717
|
+
gql_object_to_sdl(agooText text, gqlValue value, int indent, int depth) {
|
718
|
+
int i = indent * depth;
|
719
|
+
int i2 = i + indent;
|
720
|
+
int d2 = depth + 1;
|
721
|
+
gqlLink link;
|
722
|
+
|
723
|
+
if (0 < indent) {
|
724
|
+
i++; // for \n
|
725
|
+
i2++;
|
726
|
+
}
|
727
|
+
if ((int)sizeof(spaces) <= i) {
|
728
|
+
i2 = sizeof(spaces) - 1;
|
729
|
+
i = i2 - indent;
|
730
|
+
}
|
731
|
+
text = agoo_text_append(text, "{", 1);
|
732
|
+
for (link = value->members; NULL != link; link = link->next) {
|
733
|
+
if (0 < i2) {
|
734
|
+
text = agoo_text_append(text, spaces, i2);
|
735
|
+
}
|
736
|
+
text = agoo_text_append(text, link->key, -1);
|
737
|
+
if (0 < indent) {
|
738
|
+
text = agoo_text_append(text, ": ", 2);
|
739
|
+
} else {
|
740
|
+
text = agoo_text_append(text, ":", 1);
|
741
|
+
}
|
742
|
+
text = link->value->type->to_sdl(text, link->value, indent, d2);
|
661
743
|
if (NULL != link->next) {
|
662
744
|
text = agoo_text_append(text, ",", 1);
|
663
745
|
}
|
@@ -674,21 +756,29 @@ struct _gqlType object_type = { // unregistered
|
|
674
756
|
.name = "__Object",
|
675
757
|
.desc = NULL,
|
676
758
|
.kind = GQL_SCALAR,
|
677
|
-
.
|
759
|
+
.scalar_kind = GQL_SCALAR_OBJECT,
|
678
760
|
.core = true,
|
679
|
-
.coerce = NULL,
|
680
761
|
.destroy = object_destroy,
|
681
|
-
.to_json =
|
762
|
+
.to_json = gql_object_to_json,
|
763
|
+
.to_sdl = gql_object_to_sdl,
|
682
764
|
};
|
683
765
|
|
684
766
|
////////////////////////////////////////////////////////////////////////////////
|
685
767
|
void
|
686
768
|
gql_value_destroy(gqlValue value) {
|
687
|
-
if (NULL != value
|
688
|
-
value->type->
|
769
|
+
if (NULL != value) {
|
770
|
+
if (GQL_SCALAR == value->type->kind) {
|
771
|
+
if (NULL != value->type->destroy) {
|
772
|
+
value->type->destroy(value);
|
773
|
+
}
|
774
|
+
} else if (GQL_ENUM == value->type->kind) {
|
775
|
+
// TBD destroy string
|
776
|
+
string_destroy(value);
|
777
|
+
} else {
|
778
|
+
return;
|
779
|
+
}
|
780
|
+
AGOO_FREE(value);
|
689
781
|
}
|
690
|
-
DEBUG_ALLOC(mem_graphql_value, value);
|
691
|
-
free(value);
|
692
782
|
}
|
693
783
|
|
694
784
|
int
|
@@ -699,7 +789,6 @@ gql_value_init(agooErr err) {
|
|
699
789
|
AGOO_ERR_OK != gql_type_set(err, &gql_float_type) ||
|
700
790
|
AGOO_ERR_OK != gql_type_set(err, &gql_time_type) ||
|
701
791
|
AGOO_ERR_OK != gql_type_set(err, &gql_uuid_type) ||
|
702
|
-
AGOO_ERR_OK != gql_type_set(err, &gql_url_type) ||
|
703
792
|
AGOO_ERR_OK != gql_type_set(err, &gql_string_type)) {
|
704
793
|
return err->code;
|
705
794
|
}
|
@@ -723,16 +812,18 @@ int
|
|
723
812
|
gql_string_set(agooErr err, gqlValue value, const char *str, int len) {
|
724
813
|
value->type = &gql_string_type;
|
725
814
|
if (NULL == str) {
|
726
|
-
value->str =
|
815
|
+
value->str.alloced = true;
|
816
|
+
value->str.ptr = NULL;
|
727
817
|
} else {
|
728
818
|
if (0 >= len) {
|
729
819
|
len = (int)strlen(str);
|
730
820
|
}
|
731
|
-
if (len < (int)sizeof(value->
|
732
|
-
value->
|
733
|
-
|
821
|
+
if (len < (int)sizeof(value->str.a)) {
|
822
|
+
strncpy(value->str.a, str, len);
|
823
|
+
value->str.alloced = false;
|
734
824
|
} else {
|
735
|
-
|
825
|
+
value->str.alloced = true;
|
826
|
+
if (NULL == (value->str.ptr = AGOO_STRNDUP(str, len))) {
|
736
827
|
return agoo_err_set(err, AGOO_ERR_MEMORY, "strndup of length %d failed.", len);
|
737
828
|
}
|
738
829
|
}
|
@@ -741,16 +832,23 @@ gql_string_set(agooErr err, gqlValue value, const char *str, int len) {
|
|
741
832
|
}
|
742
833
|
|
743
834
|
int
|
744
|
-
|
745
|
-
value->type = &
|
746
|
-
if (NULL ==
|
747
|
-
value->
|
835
|
+
gql_token_set(agooErr err, gqlValue value, const char *str, int len) {
|
836
|
+
value->type = &gql_token_type;
|
837
|
+
if (NULL == str) {
|
838
|
+
value->str.alloced = true;
|
839
|
+
value->str.ptr = NULL;
|
748
840
|
} else {
|
749
841
|
if (0 >= len) {
|
750
|
-
len = (int)strlen(
|
842
|
+
len = (int)strlen(str);
|
751
843
|
}
|
752
|
-
if (
|
753
|
-
|
844
|
+
if (len < (int)sizeof(value->str.a)) {
|
845
|
+
strncpy(value->str.a, str, len);
|
846
|
+
value->str.alloced = false;
|
847
|
+
} else {
|
848
|
+
value->str.alloced = true;
|
849
|
+
if (NULL == (value->str.ptr = AGOO_STRNDUP(str, len))) {
|
850
|
+
return agoo_err_set(err, AGOO_ERR_MEMORY, "strndup of length %d failed.", len);
|
851
|
+
}
|
754
852
|
}
|
755
853
|
}
|
756
854
|
return AGOO_ERR_OK;
|
@@ -758,21 +856,25 @@ gql_url_set(agooErr err, gqlValue value, const char *url, int len) {
|
|
758
856
|
|
759
857
|
void
|
760
858
|
gql_bool_set(gqlValue value, bool b) {
|
859
|
+
value->type = &gql_bool_type;
|
761
860
|
value->b = b;
|
762
861
|
}
|
763
862
|
|
764
863
|
void
|
765
864
|
gql_float_set(gqlValue value, double f) {
|
865
|
+
value->type = &gql_float_type;
|
766
866
|
value->f = f;
|
767
867
|
}
|
768
868
|
|
769
869
|
void
|
770
870
|
gql_time_set(gqlValue value, int64_t t) {
|
871
|
+
value->type = &gql_time_type;
|
771
872
|
value->time = t;
|
772
873
|
}
|
773
874
|
|
774
875
|
int
|
775
876
|
gql_time_str_set(agooErr err, gqlValue value, const char *str, int len) {
|
877
|
+
value->type = &gql_time_type;
|
776
878
|
if (0 >= len) {
|
777
879
|
len = (int)strlen(str);
|
778
880
|
}
|
@@ -783,6 +885,7 @@ gql_time_str_set(agooErr err, gqlValue value, const char *str, int len) {
|
|
783
885
|
|
784
886
|
void
|
785
887
|
gql_uuid_set(gqlValue value, uint64_t hi, uint64_t lo) {
|
888
|
+
value->type = &gql_uuid_type;
|
786
889
|
value->uuid.hi = hi;
|
787
890
|
value->uuid.lo = lo;
|
788
891
|
}
|
@@ -795,6 +898,7 @@ gql_uuid_str_set(agooErr err, gqlValue value, const char *str, int len) {
|
|
795
898
|
if (AGOO_ERR_OK != parse_uuid(err, str, len, &hi, &lo)) {
|
796
899
|
return err->code;
|
797
900
|
}
|
901
|
+
value->type = &gql_uuid_type;
|
798
902
|
value->uuid.hi = hi;
|
799
903
|
value->uuid.lo = lo;
|
800
904
|
|
@@ -804,23 +908,37 @@ gql_uuid_str_set(agooErr err, gqlValue value, const char *str, int len) {
|
|
804
908
|
extern void gql_null_set(gqlValue value);
|
805
909
|
|
806
910
|
gqlLink
|
807
|
-
|
808
|
-
gqlLink link = (gqlLink)
|
911
|
+
gql_link_create(agooErr err, const char *key, gqlValue item) {
|
912
|
+
gqlLink link = (gqlLink)AGOO_MALLOC(sizeof(struct _gqlLink));
|
809
913
|
|
810
914
|
if (NULL == link) {
|
811
915
|
agoo_err_set(err, AGOO_ERR_MEMORY, "Failed to allocation memory for a list link.");
|
812
916
|
} else {
|
813
|
-
DEBUG_ALLOC(mem_graphql_link, link);
|
814
917
|
link->next = NULL;
|
815
918
|
link->key = NULL;
|
919
|
+
if (NULL != key) {
|
920
|
+
if (NULL == (link->key = AGOO_STRDUP(key))) {
|
921
|
+
agoo_err_set(err, AGOO_ERR_MEMORY, "strdup() failed.");
|
922
|
+
return NULL;
|
923
|
+
}
|
924
|
+
}
|
816
925
|
link->value = item;
|
817
926
|
}
|
818
927
|
return link;
|
819
928
|
}
|
820
929
|
|
930
|
+
void
|
931
|
+
gql_link_destroy(gqlLink link) {
|
932
|
+
AGOO_FREE(link->key);
|
933
|
+
if (NULL != link->value) {
|
934
|
+
gql_value_destroy(link->value);
|
935
|
+
}
|
936
|
+
AGOO_FREE(link);
|
937
|
+
}
|
938
|
+
|
821
939
|
int
|
822
940
|
gql_list_append(agooErr err, gqlValue list, gqlValue item) {
|
823
|
-
gqlLink link =
|
941
|
+
gqlLink link = gql_link_create(err, NULL, item);
|
824
942
|
|
825
943
|
if (NULL != link) {
|
826
944
|
if (NULL == list->members) {
|
@@ -838,7 +956,7 @@ gql_list_append(agooErr err, gqlValue list, gqlValue item) {
|
|
838
956
|
|
839
957
|
int
|
840
958
|
gql_list_prepend(agooErr err, gqlValue list, gqlValue item) {
|
841
|
-
gqlLink link =
|
959
|
+
gqlLink link = gql_link_create(err, NULL, item);
|
842
960
|
|
843
961
|
if (NULL != link) {
|
844
962
|
link->next = list->members;
|
@@ -849,10 +967,9 @@ gql_list_prepend(agooErr err, gqlValue list, gqlValue item) {
|
|
849
967
|
|
850
968
|
int
|
851
969
|
gql_object_set(agooErr err, gqlValue obj, const char *key, gqlValue item) {
|
852
|
-
gqlLink link =
|
970
|
+
gqlLink link = gql_link_create(err, key, item);
|
853
971
|
|
854
972
|
if (NULL != link) {
|
855
|
-
link->key = strdup(key);
|
856
973
|
//link->next = obj->members;
|
857
974
|
if (NULL == obj->members) {
|
858
975
|
obj->members = link;
|
@@ -871,10 +988,9 @@ gql_object_set(agooErr err, gqlValue obj, const char *key, gqlValue item) {
|
|
871
988
|
|
872
989
|
static gqlValue
|
873
990
|
value_create(gqlType type) {
|
874
|
-
gqlValue v = (gqlValue)
|
991
|
+
gqlValue v = (gqlValue)AGOO_MALLOC(sizeof(struct _gqlValue));
|
875
992
|
|
876
993
|
if (NULL != v) {
|
877
|
-
DEBUG_ALLOC(mem_graphql_value, v);
|
878
994
|
memset(v, 0, sizeof(struct _gqlValue));
|
879
995
|
v->type = type;
|
880
996
|
}
|
@@ -908,35 +1024,67 @@ gql_string_create(agooErr err, const char *str, int len) {
|
|
908
1024
|
if (0 >= len) {
|
909
1025
|
len = (int)strlen(str);
|
910
1026
|
}
|
911
|
-
if ((
|
912
|
-
if (
|
913
|
-
|
1027
|
+
if (NULL != (v = value_create(&gql_string_type))) {
|
1028
|
+
if ((int)sizeof(v->str.a) <= len) {
|
1029
|
+
v->str.alloced = true;
|
1030
|
+
if (NULL == (v->str.ptr = AGOO_STRNDUP(str, len))) {
|
914
1031
|
agoo_err_set(err, AGOO_ERR_MEMORY, "strndup of length %d failed.", len);
|
915
1032
|
return NULL;
|
916
1033
|
}
|
1034
|
+
} else {
|
1035
|
+
v->str.alloced = false;
|
1036
|
+
strncpy(v->str.a, str, len);
|
1037
|
+
v->str.a[len] = '\0';
|
917
1038
|
}
|
918
|
-
}
|
919
|
-
|
920
|
-
|
921
|
-
|
1039
|
+
}
|
1040
|
+
return v;
|
1041
|
+
}
|
1042
|
+
|
1043
|
+
gqlValue
|
1044
|
+
gql_token_create(agooErr err, const char *str, int len, gqlType type) {
|
1045
|
+
gqlValue v;
|
1046
|
+
|
1047
|
+
if (0 >= len) {
|
1048
|
+
len = (int)strlen(str);
|
1049
|
+
}
|
1050
|
+
if (NULL == type || GQL_ENUM != type->kind) {
|
1051
|
+
type = &gql_token_type;
|
1052
|
+
}
|
1053
|
+
if (NULL != (v = value_create(type))) {
|
1054
|
+
if ((int)sizeof(v->str.a) <= len) {
|
1055
|
+
v->str.alloced = true;
|
1056
|
+
if (NULL == (v->str.ptr = AGOO_STRNDUP(str, len))) {
|
1057
|
+
agoo_err_set(err, AGOO_ERR_MEMORY, "strndup of length %d failed.", len);
|
1058
|
+
return NULL;
|
1059
|
+
}
|
1060
|
+
} else {
|
1061
|
+
v->str.alloced = false;
|
1062
|
+
strncpy(v->str.a, str, len);
|
1063
|
+
v->str.a[len] = '\0';
|
922
1064
|
}
|
923
1065
|
}
|
924
1066
|
return v;
|
925
1067
|
}
|
926
1068
|
|
927
1069
|
gqlValue
|
928
|
-
|
929
|
-
gqlValue v
|
1070
|
+
gql_var_create(agooErr err, const char *str, int len) {
|
1071
|
+
gqlValue v;
|
930
1072
|
|
931
1073
|
if (0 >= len) {
|
932
|
-
len = (int)strlen(
|
1074
|
+
len = (int)strlen(str);
|
933
1075
|
}
|
934
|
-
if (NULL != v) {
|
935
|
-
if (
|
936
|
-
|
937
|
-
|
1076
|
+
if (NULL != (v = value_create(&gql_var_type))) {
|
1077
|
+
if ((int)sizeof(v->str.a) <= len) {
|
1078
|
+
v->str.alloced = true;
|
1079
|
+
if (NULL == (v->str.ptr = AGOO_STRNDUP(str, len))) {
|
1080
|
+
agoo_err_set(err, AGOO_ERR_MEMORY, "strndup of length %d failed.", len);
|
1081
|
+
return NULL;
|
1082
|
+
}
|
1083
|
+
} else {
|
1084
|
+
v->str.alloced = false;
|
1085
|
+
strncpy(v->str.a, str, len);
|
1086
|
+
v->str.a[len] = '\0';
|
938
1087
|
}
|
939
|
-
|
940
1088
|
}
|
941
1089
|
return v;
|
942
1090
|
}
|
@@ -1020,12 +1168,12 @@ gql_null_create(agooErr err) {
|
|
1020
1168
|
}
|
1021
1169
|
|
1022
1170
|
gqlValue
|
1023
|
-
gql_list_create(agooErr err, gqlType
|
1171
|
+
gql_list_create(agooErr err, gqlType item_type) {
|
1024
1172
|
gqlValue v = value_create(&list_type);
|
1025
1173
|
|
1026
1174
|
if (NULL != v) {
|
1027
1175
|
v->members = NULL;
|
1028
|
-
v->member_type =
|
1176
|
+
v->member_type = item_type;
|
1029
1177
|
}
|
1030
1178
|
return v;
|
1031
1179
|
}
|
@@ -1043,5 +1191,400 @@ gql_object_create(agooErr err) {
|
|
1043
1191
|
|
1044
1192
|
agooText
|
1045
1193
|
gql_value_json(agooText text, gqlValue value, int indent, int depth) {
|
1046
|
-
|
1194
|
+
if (NULL == value->type || GQL_SCALAR != value->type->kind) {
|
1195
|
+
if (GQL_ENUM == value->type->kind) {
|
1196
|
+
text = string_to_text(text, value, indent, depth);
|
1197
|
+
} else {
|
1198
|
+
text = agoo_text_append(text, "null", 4);
|
1199
|
+
}
|
1200
|
+
} else if (NULL == value->type->to_json) {
|
1201
|
+
text = agoo_text_append(text, "null", 4);
|
1202
|
+
} else {
|
1203
|
+
text = value->type->to_json(text, value, indent, depth);
|
1204
|
+
}
|
1205
|
+
return text;
|
1206
|
+
}
|
1207
|
+
|
1208
|
+
agooText
|
1209
|
+
gql_value_sdl(agooText text, gqlValue value, int indent, int depth) {
|
1210
|
+
if (NULL == value->type || GQL_SCALAR != value->type->kind) {
|
1211
|
+
if (GQL_ENUM == value->type->kind) {
|
1212
|
+
text = token_to_text(text, value, indent, depth);
|
1213
|
+
} else {
|
1214
|
+
text = agoo_text_append(text, "null", 4);
|
1215
|
+
}
|
1216
|
+
} else if (NULL == value->type->to_sdl) {
|
1217
|
+
text = agoo_text_append(text, "null", 4);
|
1218
|
+
} else {
|
1219
|
+
text = value->type->to_sdl(text, value, indent, depth);
|
1220
|
+
}
|
1221
|
+
return text;
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
const char*
|
1225
|
+
gql_string_get(gqlValue value) {
|
1226
|
+
const char *s = NULL;
|
1227
|
+
|
1228
|
+
if (NULL != value) {
|
1229
|
+
if (&gql_string_type == value->type || &gql_token_type == value->type || &gql_var_type == value->type ||
|
1230
|
+
GQL_ENUM == value->type->kind) {
|
1231
|
+
if (value->str.alloced) {
|
1232
|
+
s = value->str.ptr;
|
1233
|
+
} else {
|
1234
|
+
s = value->str.a;
|
1235
|
+
}
|
1236
|
+
}
|
1237
|
+
}
|
1238
|
+
return s;
|
1239
|
+
}
|
1240
|
+
|
1241
|
+
static int
|
1242
|
+
convert_to_bool(agooErr err, gqlValue value) {
|
1243
|
+
switch (value->type->scalar_kind) {
|
1244
|
+
case GQL_SCALAR_INT:
|
1245
|
+
gql_bool_set(value, 0 != value->i);
|
1246
|
+
break;
|
1247
|
+
case GQL_SCALAR_I64:
|
1248
|
+
gql_bool_set(value, 0 != value->i64);
|
1249
|
+
break;
|
1250
|
+
case GQL_SCALAR_FLOAT:
|
1251
|
+
gql_bool_set(value, 0.0 != value->f);
|
1252
|
+
break;
|
1253
|
+
case GQL_SCALAR_STRING:
|
1254
|
+
case GQL_SCALAR_TOKEN: {
|
1255
|
+
const char *s = gql_string_get(value);
|
1256
|
+
|
1257
|
+
value->type = &gql_bool_type;
|
1258
|
+
if (0 == strcasecmp("true", s)) {
|
1259
|
+
value->b = true;
|
1260
|
+
} else if (0 == strcasecmp("false", s)) {
|
1261
|
+
value->b = false;
|
1262
|
+
} else {
|
1263
|
+
agoo_err_set(err, AGOO_ERR_PARSE, "Can not coerce a String of '%s' into a Boolean value.", s);
|
1264
|
+
}
|
1265
|
+
if (value->str.alloced) {
|
1266
|
+
AGOO_FREE((char*)value->str.ptr);
|
1267
|
+
}
|
1268
|
+
break;
|
1269
|
+
}
|
1270
|
+
default:
|
1271
|
+
agoo_err_set(err, AGOO_ERR_PARSE, "Can not coerce a %s into a Boolean value.", value->type->name);
|
1272
|
+
break;
|
1273
|
+
}
|
1274
|
+
return err->code;
|
1275
|
+
}
|
1276
|
+
|
1277
|
+
static int
|
1278
|
+
convert_to_int(agooErr err, gqlValue value) {
|
1279
|
+
switch (value->type->scalar_kind) {
|
1280
|
+
case GQL_SCALAR_I64:
|
1281
|
+
if (value->i64 < INT32_MIN || INT32_MAX < value->i64) {
|
1282
|
+
agoo_err_set(err, ERANGE, "Can not coerce a %lld into an Int value. Out of range.", (long long)value->i64);
|
1283
|
+
} else {
|
1284
|
+
gql_int_set(value, (int32_t)value->i64);
|
1285
|
+
}
|
1286
|
+
break;
|
1287
|
+
case GQL_SCALAR_FLOAT:
|
1288
|
+
if (value->f < (double)INT32_MIN || (double)INT32_MAX < value->f) {
|
1289
|
+
agoo_err_set(err, ERANGE, "Can not coerce a %g into an Int value. Out of range.", value->f);
|
1290
|
+
} else if ((double)(int32_t)value->f != value->f) {
|
1291
|
+
agoo_err_set(err, ERANGE, "Can not coerce a %g into an Int value. Loss of precision.", value->f);
|
1292
|
+
} else {
|
1293
|
+
gql_int_set(value, (int32_t)value->f);
|
1294
|
+
}
|
1295
|
+
break;
|
1296
|
+
case GQL_SCALAR_STRING: {
|
1297
|
+
const char *s = gql_string_get(value);
|
1298
|
+
char *end;
|
1299
|
+
long i = strtol(s, &end, 10);
|
1300
|
+
|
1301
|
+
if ('\0' != *end || (0 == i && 0 != errno)) {
|
1302
|
+
agoo_err_set(err, ERANGE, "Can not coerce a '%s' into an Int value.", s);
|
1303
|
+
} else if (i < INT32_MIN || INT32_MAX < i) {
|
1304
|
+
agoo_err_set(err, ERANGE, "Can not coerce a %lld into an Int value. Out of range.", (long long)i);
|
1305
|
+
} else {
|
1306
|
+
gql_int_set(value, (int32_t)i);
|
1307
|
+
if (value->str.alloced) {
|
1308
|
+
AGOO_FREE((char*)value->str.ptr);
|
1309
|
+
}
|
1310
|
+
}
|
1311
|
+
break;
|
1312
|
+
}
|
1313
|
+
default:
|
1314
|
+
agoo_err_set(err, AGOO_ERR_PARSE, "Can not coerce a %s into an Int value.", value->type->name);
|
1315
|
+
break;
|
1316
|
+
}
|
1317
|
+
return err->code;
|
1318
|
+
}
|
1319
|
+
|
1320
|
+
static int
|
1321
|
+
convert_to_i64(agooErr err, gqlValue value) {
|
1322
|
+
switch (value->type->scalar_kind) {
|
1323
|
+
case GQL_SCALAR_INT:
|
1324
|
+
gql_i64_set(value, (int64_t)value->i);
|
1325
|
+
break;
|
1326
|
+
case GQL_SCALAR_FLOAT:
|
1327
|
+
if ((double)(int64_t)value->f != value->f) {
|
1328
|
+
agoo_err_set(err, ERANGE, "Can not coerce a %g into an I64 value. Loss of precision.", value->f);
|
1329
|
+
} else {
|
1330
|
+
gql_i64_set(value, (int64_t)value->f);
|
1331
|
+
}
|
1332
|
+
break;
|
1333
|
+
case GQL_SCALAR_STRING: {
|
1334
|
+
const char *s = gql_string_get(value);
|
1335
|
+
char *end;
|
1336
|
+
long long i = strtoll(s, &end, 10);
|
1337
|
+
|
1338
|
+
if ('\0' != *end || (0 == i && 0 != errno)) {
|
1339
|
+
agoo_err_set(err, ERANGE, "Can not coerce a '%s' into an I64 value.", s);
|
1340
|
+
} else {
|
1341
|
+
gql_i64_set(value, (int64_t)i);
|
1342
|
+
if (value->str.alloced) {
|
1343
|
+
AGOO_FREE((char*)value->str.ptr);
|
1344
|
+
}
|
1345
|
+
}
|
1346
|
+
break;
|
1347
|
+
}
|
1348
|
+
case GQL_SCALAR_TIME:
|
1349
|
+
gql_i64_set(value, (int64_t)value->time);
|
1350
|
+
break;
|
1351
|
+
default:
|
1352
|
+
agoo_err_set(err, AGOO_ERR_PARSE, "Can not coerce a %s into an I64 value.", value->type->name);
|
1353
|
+
break;
|
1354
|
+
}
|
1355
|
+
return err->code;
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
static int
|
1359
|
+
convert_to_float(agooErr err, gqlValue value) {
|
1360
|
+
switch (value->type->scalar_kind) {
|
1361
|
+
case GQL_SCALAR_INT:
|
1362
|
+
gql_float_set(value, (double)value->i);
|
1363
|
+
break;
|
1364
|
+
case GQL_SCALAR_I64:
|
1365
|
+
gql_float_set(value, (double)value->i64);
|
1366
|
+
break;
|
1367
|
+
case GQL_SCALAR_STRING: {
|
1368
|
+
const char *s = gql_string_get(value);
|
1369
|
+
char *end;
|
1370
|
+
double d = strtod(s, &end);
|
1371
|
+
|
1372
|
+
if ('\0' != *end) {
|
1373
|
+
agoo_err_set(err, ERANGE, "Can not coerce a '%s' into a Float value.", s);
|
1374
|
+
} else {
|
1375
|
+
gql_float_set(value, d);
|
1376
|
+
if (value->str.alloced) {
|
1377
|
+
AGOO_FREE((char*)value->str.ptr);
|
1378
|
+
}
|
1379
|
+
}
|
1380
|
+
break;
|
1381
|
+
}
|
1382
|
+
case GQL_SCALAR_TIME:
|
1383
|
+
gql_float_set(value, (double)value->time / 1000000000.0);
|
1384
|
+
break;
|
1385
|
+
default:
|
1386
|
+
agoo_err_set(err, AGOO_ERR_PARSE, "Can not coerce a %s into a Float value.", value->type->name);
|
1387
|
+
break;
|
1388
|
+
}
|
1389
|
+
return err->code;
|
1390
|
+
}
|
1391
|
+
|
1392
|
+
static int
|
1393
|
+
convert_to_string(agooErr err, gqlValue value) {
|
1394
|
+
char buf[64];
|
1395
|
+
int cnt;
|
1396
|
+
|
1397
|
+
switch (value->type->scalar_kind) {
|
1398
|
+
case GQL_SCALAR_BOOL:
|
1399
|
+
if (value->b) {
|
1400
|
+
gql_string_set(err, value, "true", 4);
|
1401
|
+
} else {
|
1402
|
+
gql_string_set(err, value, "false", 5);
|
1403
|
+
}
|
1404
|
+
break;
|
1405
|
+
case GQL_SCALAR_INT:
|
1406
|
+
cnt = sprintf(buf, "%d", value->i);
|
1407
|
+
gql_string_set(err, value, buf, cnt);
|
1408
|
+
break;
|
1409
|
+
case GQL_SCALAR_I64:
|
1410
|
+
cnt = sprintf(buf, "%lld", (long long)value->i64);
|
1411
|
+
gql_string_set(err, value, buf, cnt);
|
1412
|
+
break;
|
1413
|
+
case GQL_SCALAR_FLOAT:
|
1414
|
+
cnt = sprintf(buf, "%g", value->f);
|
1415
|
+
gql_string_set(err, value, buf, cnt);
|
1416
|
+
break;
|
1417
|
+
case GQL_SCALAR_TOKEN:
|
1418
|
+
value->type = &gql_string_type;
|
1419
|
+
break;
|
1420
|
+
case GQL_SCALAR_TIME: {
|
1421
|
+
struct _agooTime at;
|
1422
|
+
int64_t tt = value->time;
|
1423
|
+
time_t t = (time_t)(tt / 1000000000LL);
|
1424
|
+
long nsecs = tt - (int64_t)t * 1000000000LL;
|
1425
|
+
|
1426
|
+
if (0 > nsecs) {
|
1427
|
+
nsecs = -nsecs;
|
1428
|
+
}
|
1429
|
+
agoo_sectime(t, &at);
|
1430
|
+
cnt = sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ", at.year, at.mon, at.day, at.hour, at.min, at.sec, (long)nsecs);
|
1431
|
+
gql_string_set(err, value, buf, cnt);
|
1432
|
+
break;
|
1433
|
+
}
|
1434
|
+
case GQL_SCALAR_UUID:
|
1435
|
+
cnt = sprintf(buf, "%08lx-%04lx-%04lx-%04lx-%012lx",
|
1436
|
+
(unsigned long)(value->uuid.hi >> 32),
|
1437
|
+
(unsigned long)((value->uuid.hi >> 16) & 0x000000000000FFFFUL),
|
1438
|
+
(unsigned long)(value->uuid.hi & 0x000000000000FFFFUL),
|
1439
|
+
(unsigned long)(value->uuid.lo >> 48),
|
1440
|
+
(unsigned long)(value->uuid.lo & 0x0000FFFFFFFFFFFFUL));
|
1441
|
+
gql_string_set(err, value, buf, cnt);
|
1442
|
+
break;
|
1443
|
+
default:
|
1444
|
+
agoo_err_set(err, AGOO_ERR_PARSE, "Can not coerce a %s into a String value.", value->type->name);
|
1445
|
+
break;
|
1446
|
+
}
|
1447
|
+
return err->code;
|
1448
|
+
}
|
1449
|
+
|
1450
|
+
static int
|
1451
|
+
convert_to_token(agooErr err, gqlValue value) {
|
1452
|
+
switch (value->type->scalar_kind) {
|
1453
|
+
case GQL_SCALAR_STRING:
|
1454
|
+
value->type = &gql_token_type;
|
1455
|
+
break;
|
1456
|
+
default:
|
1457
|
+
agoo_err_set(err, AGOO_ERR_PARSE, "Can not coerce a %s into a token value.", value->type->name);
|
1458
|
+
break;
|
1459
|
+
}
|
1460
|
+
return err->code;
|
1461
|
+
}
|
1462
|
+
|
1463
|
+
static int
|
1464
|
+
convert_to_time(agooErr err, gqlValue value) {
|
1465
|
+
switch (value->type->scalar_kind) {
|
1466
|
+
case GQL_SCALAR_I64:
|
1467
|
+
gql_time_set(value, value->i64);
|
1468
|
+
break;
|
1469
|
+
case GQL_SCALAR_STRING: {
|
1470
|
+
int64_t nsecs = time_parse(err, gql_string_get(value), -1);
|
1471
|
+
|
1472
|
+
if (AGOO_ERR_OK == err->code) {
|
1473
|
+
if (value->str.alloced) {
|
1474
|
+
AGOO_FREE((char*)value->str.ptr);
|
1475
|
+
}
|
1476
|
+
gql_time_set(value, nsecs);
|
1477
|
+
}
|
1478
|
+
break;
|
1479
|
+
}
|
1480
|
+
default:
|
1481
|
+
agoo_err_set(err, AGOO_ERR_PARSE, "Can not coerce a %s into a Time value.", value->type->name);
|
1482
|
+
break;
|
1483
|
+
}
|
1484
|
+
return err->code;
|
1485
|
+
}
|
1486
|
+
|
1487
|
+
static int
|
1488
|
+
convert_to_uuid(agooErr err, gqlValue value) {
|
1489
|
+
switch (value->type->scalar_kind) {
|
1490
|
+
case GQL_SCALAR_STRING: {
|
1491
|
+
const char *s = gql_string_get(value);
|
1492
|
+
bool alloced = value->str.alloced;
|
1493
|
+
|
1494
|
+
if (AGOO_ERR_OK == gql_uuid_str_set(err, value, s, 0)) {
|
1495
|
+
if (alloced) {
|
1496
|
+
AGOO_FREE((char*)s);
|
1497
|
+
}
|
1498
|
+
}
|
1499
|
+
break;
|
1500
|
+
}
|
1501
|
+
default:
|
1502
|
+
agoo_err_set(err, AGOO_ERR_PARSE, "Can not coerce a %s into a UUID value.", value->type->name);
|
1503
|
+
break;
|
1504
|
+
}
|
1505
|
+
return err->code;
|
1506
|
+
}
|
1507
|
+
|
1508
|
+
int
|
1509
|
+
gql_value_convert(agooErr err, gqlValue value, struct _gqlType *type) {
|
1510
|
+
int code = AGOO_ERR_OK;
|
1511
|
+
|
1512
|
+
if (type != value->type) {
|
1513
|
+
switch (type->scalar_kind) {
|
1514
|
+
case GQL_SCALAR_BOOL:
|
1515
|
+
code = convert_to_bool(err, value);
|
1516
|
+
break;
|
1517
|
+
case GQL_SCALAR_INT:
|
1518
|
+
code = convert_to_int(err, value);
|
1519
|
+
break;
|
1520
|
+
case GQL_SCALAR_I64:
|
1521
|
+
code = convert_to_i64(err, value);
|
1522
|
+
break;
|
1523
|
+
case GQL_SCALAR_FLOAT:
|
1524
|
+
code = convert_to_float(err, value);
|
1525
|
+
break;
|
1526
|
+
case GQL_SCALAR_STRING:
|
1527
|
+
code = convert_to_string(err, value);
|
1528
|
+
break;
|
1529
|
+
case GQL_SCALAR_TOKEN:
|
1530
|
+
code = convert_to_token(err, value);
|
1531
|
+
break;
|
1532
|
+
case GQL_SCALAR_TIME:
|
1533
|
+
code = convert_to_time(err, value);
|
1534
|
+
break;
|
1535
|
+
case GQL_SCALAR_UUID:
|
1536
|
+
code = convert_to_uuid(err, value);
|
1537
|
+
break;
|
1538
|
+
default:
|
1539
|
+
break;
|
1540
|
+
}
|
1541
|
+
}
|
1542
|
+
return code;
|
1047
1543
|
}
|
1544
|
+
|
1545
|
+
gqlValue
|
1546
|
+
gql_value_dup(agooErr err, gqlValue value) {
|
1547
|
+
gqlValue dup = value_create(value->type);
|
1548
|
+
|
1549
|
+
if (NULL == dup) {
|
1550
|
+
agoo_err_set(err, AGOO_ERR_MEMORY, "failed to duplicate a value.");
|
1551
|
+
return NULL;
|
1552
|
+
}
|
1553
|
+
switch (value->type->scalar_kind) {
|
1554
|
+
case GQL_SCALAR_BOOL:
|
1555
|
+
dup->b = value->b;
|
1556
|
+
break;
|
1557
|
+
case GQL_SCALAR_INT:
|
1558
|
+
dup->i = value->i;
|
1559
|
+
break;
|
1560
|
+
case GQL_SCALAR_I64:
|
1561
|
+
dup->i64 = value->i64;
|
1562
|
+
break;
|
1563
|
+
case GQL_SCALAR_FLOAT:
|
1564
|
+
dup->f = value->f;
|
1565
|
+
break;
|
1566
|
+
case GQL_SCALAR_STRING:
|
1567
|
+
case GQL_SCALAR_TOKEN:
|
1568
|
+
if (value->str.alloced) {
|
1569
|
+
if (NULL == (dup->str.ptr = strdup(value->str.ptr))) {
|
1570
|
+
agoo_err_set(err, AGOO_ERR_MEMORY, "strdup of length %d failed.", strlen(value->str.ptr));
|
1571
|
+
AGOO_FREE(dup);
|
1572
|
+
dup = NULL;
|
1573
|
+
}
|
1574
|
+
} else {
|
1575
|
+
memcpy(dup->str.a, value->str.a, sizeof(value->str.a));
|
1576
|
+
}
|
1577
|
+
break;
|
1578
|
+
case GQL_SCALAR_TIME:
|
1579
|
+
dup->time = value->time;
|
1580
|
+
break;
|
1581
|
+
case GQL_SCALAR_UUID:
|
1582
|
+
dup->uuid.hi = value->uuid.hi;
|
1583
|
+
dup->uuid.lo = value->uuid.lo;
|
1584
|
+
break;
|
1585
|
+
default:
|
1586
|
+
break;
|
1587
|
+
}
|
1588
|
+
return dup;
|
1589
|
+
}
|
1590
|
+
|