aboutsummaryrefslogtreecommitdiff
path: root/src/pq/pq_query_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pq/pq_query_helper.c')
-rw-r--r--src/pq/pq_query_helper.c259
1 files changed, 221 insertions, 38 deletions
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
index a7455fc5f..b2bbe8ad4 100644
--- a/src/pq/pq_query_helper.c
+++ b/src/pq/pq_query_helper.c
@@ -24,6 +24,7 @@
24 */ 24 */
25#include "gnunet_common.h" 25#include "gnunet_common.h"
26#include "gnunet_pq_lib.h" 26#include "gnunet_pq_lib.h"
27#include "gnunet_time_lib.h"
27#include "platform.h" 28#include "platform.h"
28#include "pq.h" 29#include "pq.h"
29 30
@@ -589,6 +590,24 @@ struct pq_array_header
589} __attribute__((packed)); 590} __attribute__((packed));
590 591
591/** 592/**
593 * Internal types that are supported as array types.
594 */
595
596enum array_types
597{
598 array_of_bool,
599 array_of_uint16,
600 array_of_uint32,
601 array_of_uint64,
602 array_of_byte, /* buffers of (char *), (void *), ... */
603 array_of_string, /* NULL-terminated (char *) */
604 array_of_abs_time,
605 array_of_rel_time,
606 array_of_timestamp,
607 array_of_MAX, /* must be last */
608};
609
610/**
592 * Closure for the array type handlers. 611 * Closure for the array type handlers.
593 * 612 *
594 * May contain sizes information for the data, given (and handled) by the 613 * May contain sizes information for the data, given (and handled) by the
@@ -620,7 +639,7 @@ struct qconv_array_cls
620 /** 639 /**
621 * Type of the array elements 640 * Type of the array elements
622 */ 641 */
623 enum GNUNET_PQ_DataTypes typ; 642 enum array_types typ;
624 643
625 /** 644 /**
626 * Oid of the array elements 645 * Oid of the array elements
@@ -674,7 +693,6 @@ qconv_array (
674 size_t total_size; 693 size_t total_size;
675 const size_t *sizes; 694 const size_t *sizes;
676 bool same_sized; 695 bool same_sized;
677 bool is_string_array;
678 size_t *string_lengths = NULL; 696 size_t *string_lengths = NULL;
679 void *elements = NULL; 697 void *elements = NULL;
680 bool noerror = true; 698 bool noerror = true;
@@ -687,7 +705,6 @@ qconv_array (
687 705
688 sizes = meta->sizes; 706 sizes = meta->sizes;
689 same_sized = (0 != meta->same_size); 707 same_sized = (0 != meta->same_size);
690 is_string_array = (GNUNET_PQ_DATATYPE_VARCHAR == meta->typ);
691 708
692#define RETURN_UNLESS(cond) \ 709#define RETURN_UNLESS(cond) \
693 do { \ 710 do { \
@@ -724,7 +741,7 @@ qconv_array (
724 else /* sizes are different per element */ 741 else /* sizes are different per element */
725 { 742 {
726 /* for an array of strings we need to get their length's first */ 743 /* for an array of strings we need to get their length's first */
727 if (is_string_array) 744 if (array_of_string == meta->typ)
728 { 745 {
729 string_lengths = GNUNET_new_array (num, size_t); 746 string_lengths = GNUNET_new_array (num, size_t);
730 747
@@ -787,37 +804,38 @@ qconv_array (
787 804
788 switch (meta->typ) 805 switch (meta->typ)
789 { 806 {
790 case GNUNET_PQ_DATATYPE_INT2: 807 case array_of_bool:
808 {
809 GNUNET_assert (sizeof(bool) == sz);
810 GNUNET_memcpy (out, in, sz);
811 in += sz;
812 break;
813 }
814 case array_of_uint16:
791 { 815 {
792 GNUNET_assert (sizeof(uint16_t) == sz); 816 GNUNET_assert (sizeof(uint16_t) == sz);
793 *(uint16_t *) out = htons (*(uint16_t *) in); 817 *(uint16_t *) out = htons (*(uint16_t *) in);
794 in += sz; 818 in += sz;
795 break; 819 break;
796 } 820 }
797 case GNUNET_PQ_DATATYPE_INT4: 821 case array_of_uint32:
798 { 822 {
799 GNUNET_assert (sizeof(uint32_t) == sz); 823 GNUNET_assert (sizeof(uint32_t) == sz);
800 *(uint32_t *) out = htonl (*(uint32_t *) in); 824 *(uint32_t *) out = htonl (*(uint32_t *) in);
801 in += sz; 825 in += sz;
802 break; 826 break;
803 } 827 }
804 case GNUNET_PQ_DATATYPE_INT8: 828 case array_of_uint64:
805 { 829 {
806 GNUNET_assert (sizeof(uint64_t) == sz); 830 GNUNET_assert (sizeof(uint64_t) == sz);
807 *(uint64_t *) out = GNUNET_htonll (*(uint64_t *) in); 831 *(uint64_t *) out = GNUNET_htonll (*(uint64_t *) in);
808 in += sz; 832 in += sz;
809 break; 833 break;
810 } 834 }
811 case GNUNET_PQ_DATATYPE_BOOL: 835 case array_of_byte:
812 {
813 GNUNET_assert (sizeof(bool) == sz);
814 GNUNET_memcpy (out, in, sz);
815 in += sz;
816 break;
817 }
818 case GNUNET_PQ_DATATYPE_BYTEA:
819 { 836 {
820 const void *ptr; 837 const void *ptr;
838
821 if (meta->continuous) 839 if (meta->continuous)
822 { 840 {
823 ptr = in; 841 ptr = in;
@@ -829,7 +847,7 @@ qconv_array (
829 GNUNET_memcpy (out, ptr, sz); 847 GNUNET_memcpy (out, ptr, sz);
830 break; 848 break;
831 } 849 }
832 case GNUNET_PQ_DATATYPE_VARCHAR: 850 case array_of_string:
833 { 851 {
834 const void *ptr; 852 const void *ptr;
835 if (meta->continuous) 853 if (meta->continuous)
@@ -843,6 +861,63 @@ qconv_array (
843 GNUNET_memcpy (out, ptr, sz); 861 GNUNET_memcpy (out, ptr, sz);
844 break; 862 break;
845 } 863 }
864 case array_of_abs_time:
865 {
866 const struct GNUNET_TIME_Absolute *abs;
867
868 if (meta->continuous)
869 {
870 abs = (const struct GNUNET_TIME_Absolute *) in;
871 in += sz;
872 }
873 else
874 abs = ((const struct GNUNET_TIME_Absolute **) data)[i];
875
876 if (abs->abs_value_us > INT64_MAX)
877 *(uint64_t *) out = GNUNET_htonll (INT64_MAX);
878 else
879 *(uint64_t *) out = GNUNET_htonll (abs->abs_value_us);
880
881 break;
882 }
883 case array_of_rel_time:
884 {
885 const struct GNUNET_TIME_Relative *rel;
886
887 if (meta->continuous)
888 {
889 rel = (const struct GNUNET_TIME_Relative *) in;
890 in += sz;
891 }
892 else
893 rel = ((const struct GNUNET_TIME_Relative **) data)[i];
894
895 if (rel->rel_value_us > INT64_MAX)
896 *(uint64_t *) out = GNUNET_htonll (INT64_MAX);
897 else
898 *(uint64_t *) out = GNUNET_htonll (rel->rel_value_us);
899
900 break;
901 }
902 case array_of_timestamp:
903 {
904 const struct GNUNET_TIME_Timestamp *ts;
905
906 if (meta->continuous)
907 {
908 ts = (const struct GNUNET_TIME_Timestamp *) in;
909 in += sz;
910 }
911 else
912 ts = ((const struct GNUNET_TIME_Timestamp **) data)[i];
913
914 if (ts->abs_time.abs_value_us > INT64_MAX)
915 *(uint64_t *) out = GNUNET_htonll (INT64_MAX);
916 else
917 *(uint64_t *) out = GNUNET_htonll (ts->abs_time.abs_value_us);
918
919 break;
920 }
846 default: 921 default:
847 { 922 {
848 GNUNET_assert (0); 923 GNUNET_assert (0);
@@ -868,14 +943,26 @@ qconv_array (
868} 943}
869 944
870 945
946/**
947 * Function to genreate a typ specific query parameter and corresponding closure
948 *
949 * @param num Number of elements in @a elements
950 * @param continuous If true, @a elements is an continuous array of data
951 * @param elements Array of @a num elements, either continuous or pointers
952 * @param sizes Array of @a num sizes, one per element, may be NULL
953 * @param same_size If not 0, all elements in @a elements have this size
954 * @param typ Supported internal type of each element in @a elements
955 * @param oid Oid of the type to be used in Postgres
956 * @return Query parameter
957 */
871static struct GNUNET_PQ_QueryParam 958static struct GNUNET_PQ_QueryParam
872query_param_array_generic ( 959query_param_array_generic (
873 unsigned int num, 960 unsigned int num,
961 bool continuous,
874 const void *elements, 962 const void *elements,
875 const size_t *sizes, 963 const size_t *sizes,
876 bool continuous,
877 size_t same_size, 964 size_t same_size,
878 enum GNUNET_PQ_DataTypes typ, 965 enum array_types typ,
879 Oid oid) 966 Oid oid)
880{ 967{
881 struct qconv_array_cls *meta = GNUNET_new (struct qconv_array_cls); 968 struct qconv_array_cls *meta = GNUNET_new (struct qconv_array_cls);
@@ -905,11 +992,11 @@ GNUNET_PQ_query_param_array_bool (
905 const struct GNUNET_PQ_Context *db) 992 const struct GNUNET_PQ_Context *db)
906{ 993{
907 return query_param_array_generic (num, 994 return query_param_array_generic (num,
995 true,
908 elements, 996 elements,
909 NULL, 997 NULL,
910 true,
911 sizeof(bool), 998 sizeof(bool),
912 GNUNET_PQ_DATATYPE_BOOL, 999 array_of_bool,
913 db->oids[GNUNET_PQ_DATATYPE_BOOL]); 1000 db->oids[GNUNET_PQ_DATATYPE_BOOL]);
914} 1001}
915 1002
@@ -921,11 +1008,11 @@ GNUNET_PQ_query_param_array_uint16 (
921 const struct GNUNET_PQ_Context *db) 1008 const struct GNUNET_PQ_Context *db)
922{ 1009{
923 return query_param_array_generic (num, 1010 return query_param_array_generic (num,
1011 true,
924 elements, 1012 elements,
925 NULL, 1013 NULL,
926 true,
927 sizeof(uint16_t), 1014 sizeof(uint16_t),
928 GNUNET_PQ_DATATYPE_INT2, 1015 array_of_uint16,
929 db->oids[GNUNET_PQ_DATATYPE_INT2]); 1016 db->oids[GNUNET_PQ_DATATYPE_INT2]);
930} 1017}
931 1018
@@ -937,11 +1024,11 @@ GNUNET_PQ_query_param_array_uint32 (
937 const struct GNUNET_PQ_Context *db) 1024 const struct GNUNET_PQ_Context *db)
938{ 1025{
939 return query_param_array_generic (num, 1026 return query_param_array_generic (num,
1027 true,
940 elements, 1028 elements,
941 NULL, 1029 NULL,
942 true,
943 sizeof(uint32_t), 1030 sizeof(uint32_t),
944 GNUNET_PQ_DATATYPE_INT4, 1031 array_of_uint32,
945 db->oids[GNUNET_PQ_DATATYPE_INT4]); 1032 db->oids[GNUNET_PQ_DATATYPE_INT4]);
946} 1033}
947 1034
@@ -953,11 +1040,11 @@ GNUNET_PQ_query_param_array_uint64 (
953 const struct GNUNET_PQ_Context *db) 1040 const struct GNUNET_PQ_Context *db)
954{ 1041{
955 return query_param_array_generic (num, 1042 return query_param_array_generic (num,
1043 true,
956 elements, 1044 elements,
957 NULL, 1045 NULL,
958 true,
959 sizeof(uint64_t), 1046 sizeof(uint64_t),
960 GNUNET_PQ_DATATYPE_INT8, 1047 array_of_uint64,
961 db->oids[GNUNET_PQ_DATATYPE_INT8]); 1048 db->oids[GNUNET_PQ_DATATYPE_INT8]);
962} 1049}
963 1050
@@ -970,11 +1057,11 @@ GNUNET_PQ_query_param_array_bytes (
970 const struct GNUNET_PQ_Context *db) 1057 const struct GNUNET_PQ_Context *db)
971{ 1058{
972 return query_param_array_generic (num, 1059 return query_param_array_generic (num,
1060 true,
973 elements, 1061 elements,
974 sizes, 1062 sizes,
975 true,
976 0, 1063 0,
977 GNUNET_PQ_DATATYPE_BYTEA, 1064 array_of_byte,
978 db->oids[GNUNET_PQ_DATATYPE_BYTEA]); 1065 db->oids[GNUNET_PQ_DATATYPE_BYTEA]);
979} 1066}
980 1067
@@ -987,11 +1074,11 @@ GNUNET_PQ_query_param_array_ptrs_bytes (
987 const struct GNUNET_PQ_Context *db) 1074 const struct GNUNET_PQ_Context *db)
988{ 1075{
989 return query_param_array_generic (num, 1076 return query_param_array_generic (num,
1077 false,
990 elements, 1078 elements,
991 sizes, 1079 sizes,
992 false,
993 0, 1080 0,
994 GNUNET_PQ_DATATYPE_BYTEA, 1081 array_of_byte,
995 db->oids[GNUNET_PQ_DATATYPE_BYTEA]); 1082 db->oids[GNUNET_PQ_DATATYPE_BYTEA]);
996} 1083}
997 1084
@@ -1004,11 +1091,11 @@ GNUNET_PQ_query_param_array_bytes_same_size (
1004 const struct GNUNET_PQ_Context *db) 1091 const struct GNUNET_PQ_Context *db)
1005{ 1092{
1006 return query_param_array_generic (num, 1093 return query_param_array_generic (num,
1094 true,
1007 elements, 1095 elements,
1008 NULL, 1096 NULL,
1009 true,
1010 same_size, 1097 same_size,
1011 GNUNET_PQ_DATATYPE_BYTEA, 1098 array_of_byte,
1012 db->oids[GNUNET_PQ_DATATYPE_BYTEA]); 1099 db->oids[GNUNET_PQ_DATATYPE_BYTEA]);
1013} 1100}
1014 1101
@@ -1021,11 +1108,11 @@ GNUNET_PQ_query_param_array_ptrs_bytes_same_size (
1021 const struct GNUNET_PQ_Context *db) 1108 const struct GNUNET_PQ_Context *db)
1022{ 1109{
1023 return query_param_array_generic (num, 1110 return query_param_array_generic (num,
1111 false,
1024 elements, 1112 elements,
1025 NULL, 1113 NULL,
1026 false,
1027 same_size, 1114 same_size,
1028 GNUNET_PQ_DATATYPE_BYTEA, 1115 array_of_byte,
1029 db->oids[GNUNET_PQ_DATATYPE_BYTEA]); 1116 db->oids[GNUNET_PQ_DATATYPE_BYTEA]);
1030} 1117}
1031 1118
@@ -1037,11 +1124,11 @@ GNUNET_PQ_query_param_array_string (
1037 const struct GNUNET_PQ_Context *db) 1124 const struct GNUNET_PQ_Context *db)
1038{ 1125{
1039 return query_param_array_generic (num, 1126 return query_param_array_generic (num,
1127 true,
1040 elements, 1128 elements,
1041 NULL, 1129 NULL,
1042 true,
1043 0, 1130 0,
1044 GNUNET_PQ_DATATYPE_VARCHAR, 1131 array_of_string,
1045 db->oids[GNUNET_PQ_DATATYPE_VARCHAR]); 1132 db->oids[GNUNET_PQ_DATATYPE_VARCHAR]);
1046} 1133}
1047 1134
@@ -1053,13 +1140,109 @@ GNUNET_PQ_query_param_array_ptrs_string (
1053 const struct GNUNET_PQ_Context *db) 1140 const struct GNUNET_PQ_Context *db)
1054{ 1141{
1055 return query_param_array_generic (num, 1142 return query_param_array_generic (num,
1143 false,
1056 elements, 1144 elements,
1057 NULL, 1145 NULL,
1058 false,
1059 0, 1146 0,
1060 GNUNET_PQ_DATATYPE_VARCHAR, 1147 array_of_string,
1061 db->oids[GNUNET_PQ_DATATYPE_VARCHAR]); 1148 db->oids[GNUNET_PQ_DATATYPE_VARCHAR]);
1062} 1149}
1063 1150
1064 1151
1152struct GNUNET_PQ_QueryParam
1153GNUNET_PQ_query_param_array_abs_time (
1154 unsigned int num,
1155 const struct GNUNET_TIME_Absolute *elements,
1156 const struct GNUNET_PQ_Context *db)
1157{
1158 return query_param_array_generic (num,
1159 true,
1160 elements,
1161 NULL,
1162 sizeof(struct GNUNET_TIME_Absolute),
1163 array_of_abs_time,
1164 db->oids[GNUNET_PQ_DATATYPE_INT8]);
1165}
1166
1167
1168struct GNUNET_PQ_QueryParam
1169GNUNET_PQ_query_param_array_ptrs_abs_time (
1170 unsigned int num,
1171 const struct GNUNET_TIME_Absolute *elements[],
1172 const struct GNUNET_PQ_Context *db)
1173{
1174 return query_param_array_generic (num,
1175 false,
1176 elements,
1177 NULL,
1178 sizeof(struct GNUNET_TIME_Absolute),
1179 array_of_abs_time,
1180 db->oids[GNUNET_PQ_DATATYPE_INT8]);
1181}
1182
1183
1184struct GNUNET_PQ_QueryParam
1185GNUNET_PQ_query_param_array_rel_time (
1186 unsigned int num,
1187 const struct GNUNET_TIME_Relative *elements,
1188 const struct GNUNET_PQ_Context *db)
1189{
1190 return query_param_array_generic (num,
1191 true,
1192 elements,
1193 NULL,
1194 sizeof(struct GNUNET_TIME_Relative),
1195 array_of_abs_time,
1196 db->oids[GNUNET_PQ_DATATYPE_INT8]);
1197}
1198
1199
1200struct GNUNET_PQ_QueryParam
1201GNUNET_PQ_query_param_array_ptrs_rel_time (
1202 unsigned int num,
1203 const struct GNUNET_TIME_Relative *elements[],
1204 const struct GNUNET_PQ_Context *db)
1205{
1206 return query_param_array_generic (num,
1207 false,
1208 elements,
1209 NULL,
1210 sizeof(struct GNUNET_TIME_Relative),
1211 array_of_abs_time,
1212 db->oids[GNUNET_PQ_DATATYPE_INT8]);
1213}
1214
1215
1216struct GNUNET_PQ_QueryParam
1217GNUNET_PQ_query_param_array_timestamp (
1218 unsigned int num,
1219 const struct GNUNET_TIME_Timestamp *elements,
1220 const struct GNUNET_PQ_Context *db)
1221{
1222 return query_param_array_generic (num,
1223 true,
1224 elements,
1225 NULL,
1226 sizeof(struct GNUNET_TIME_Timestamp),
1227 array_of_timestamp,
1228 db->oids[GNUNET_PQ_DATATYPE_INT8]);
1229}
1230
1231
1232struct GNUNET_PQ_QueryParam
1233GNUNET_PQ_query_param_array_ptrs_timestamp (
1234 unsigned int num,
1235 const struct GNUNET_TIME_Timestamp *elements[],
1236 const struct GNUNET_PQ_Context *db)
1237{
1238 return query_param_array_generic (num,
1239 false,
1240 elements,
1241 NULL,
1242 sizeof(struct GNUNET_TIME_Timestamp),
1243 array_of_timestamp,
1244 db->oids[GNUNET_PQ_DATATYPE_INT8]);
1245}
1246
1247
1065/* end of pq_query_helper.c */ 1248/* end of pq_query_helper.c */