aboutsummaryrefslogtreecommitdiff
path: root/src/peerstore
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-05-14 16:40:45 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-05-14 16:40:45 +0000
commita760c1b877f3a9ac17f2577cdc298f793c574407 (patch)
tree7411c99a1865aa1b1a6e1141172aa9a1378d4db7 /src/peerstore
parentcb67c0bb1e6f2a5bae0295a75bc1f4b1b9f9f765 (diff)
downloadgnunet-a760c1b877f3a9ac17f2577cdc298f793c574407.tar.gz
gnunet-a760c1b877f3a9ac17f2577cdc298f793c574407.zip
peerstore helper file
Diffstat (limited to 'src/peerstore')
-rw-r--r--src/peerstore/Makefile.am9
-rw-r--r--src/peerstore/gnunet-service-peerstore.c73
-rw-r--r--src/peerstore/peerstore.h20
-rw-r--r--src/peerstore/peerstore_api.c33
-rw-r--r--src/peerstore/peerstore_common.c139
-rw-r--r--src/peerstore/peerstore_common.h93
-rw-r--r--src/peerstore/plugin_peerstore_sqlite.c136
7 files changed, 371 insertions, 132 deletions
diff --git a/src/peerstore/Makefile.am b/src/peerstore/Makefile.am
index 4c4c84ed1..b7b7f3ea5 100644
--- a/src/peerstore/Makefile.am
+++ b/src/peerstore/Makefile.am
@@ -27,20 +27,23 @@ lib_LTLIBRARIES = \
27 libgnunetpeerstore.la 27 libgnunetpeerstore.la
28 28
29gnunet_peerstore_SOURCES = \ 29gnunet_peerstore_SOURCES = \
30 gnunet-peerstore.c 30 gnunet-peerstore.c
31gnunet_peerstore_LDADD = \ 31gnunet_peerstore_LDADD = \
32 $(top_builddir)/src/util/libgnunetutil.la \ 32 $(top_builddir)/src/util/libgnunetutil.la \
33 libgnunetpeerstore.la \ 33 libgnunetpeerstore.la \
34 $(GN_LIBINTL) 34 $(GN_LIBINTL)
35 35
36gnunet_service_peerstore_SOURCES = \ 36gnunet_service_peerstore_SOURCES = \
37 gnunet-service-peerstore.c 37 gnunet-service-peerstore.c \
38 peerstore_common.c
39gnunet_service_peerstore_CFLAGS = $(AM_CFLAGS)
38gnunet_service_peerstore_LDADD = \ 40gnunet_service_peerstore_LDADD = \
39 $(top_builddir)/src/util/libgnunetutil.la \ 41 $(top_builddir)/src/util/libgnunetutil.la \
40 $(GN_LIBINTL) 42 $(GN_LIBINTL)
41 43
42libgnunetpeerstore_la_SOURCES = \ 44libgnunetpeerstore_la_SOURCES = \
43 peerstore_api.c 45 peerstore_api.c \
46 peerstore_common.c
44libgnunetpeerstore_la_LIBADD = \ 47libgnunetpeerstore_la_LIBADD = \
45 $(top_builddir)/src/util/libgnunetutil.la 48 $(top_builddir)/src/util/libgnunetutil.la
46libgnunetpeerstore_la_LDFLAGS = \ 49libgnunetpeerstore_la_LDFLAGS = \
diff --git a/src/peerstore/gnunet-service-peerstore.c b/src/peerstore/gnunet-service-peerstore.c
index 303f25027..990fa2c88 100644
--- a/src/peerstore/gnunet-service-peerstore.c
+++ b/src/peerstore/gnunet-service-peerstore.c
@@ -27,6 +27,7 @@
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "peerstore.h" 28#include "peerstore.h"
29#include "gnunet_peerstore_plugin.h" 29#include "gnunet_peerstore_plugin.h"
30#include "peerstore_common.h"
30 31
31//TODO: GNUNET_SERVER_receive_done() ? 32//TODO: GNUNET_SERVER_receive_done() ?
32//TODO: implement value lifetime 33//TODO: implement value lifetime
@@ -79,6 +80,20 @@ handle_client_disconnect (void *cls,
79} 80}
80 81
81/** 82/**
83 * Handle an iterate request from client
84 *
85 * @param cls unused
86 * @param client identification of the client
87 * @param message the actual message
88 */
89void handle_iterate (void *cls,
90 struct GNUNET_SERVER_Client *client,
91 const struct GNUNET_MessageHeader *message)
92{
93
94}
95
96/**
82 * Handle a store request from client 97 * Handle a store request from client
83 * 98 *
84 * @param cls unused 99 * @param cls unused
@@ -89,49 +104,46 @@ void handle_store (void *cls,
89 struct GNUNET_SERVER_Client *client, 104 struct GNUNET_SERVER_Client *client,
90 const struct GNUNET_MessageHeader *message) 105 const struct GNUNET_MessageHeader *message)
91{ 106{
92 struct StoreRequestMessage *req; 107 struct GNUNET_PEERSTORE_Record *record;
93 uint16_t req_size;
94 uint16_t ss_size;
95 uint16_t key_size;
96 uint16_t value_size;
97 char *sub_system;
98 char *key;
99 void *value;
100 uint16_t response_type; 108 uint16_t response_type;
101 struct GNUNET_SERVER_TransmitContext *tc; 109 struct GNUNET_SERVER_TransmitContext *tc;
102 110
103 req_size = ntohs(message->size); 111 record = PEERSTORE_parse_record_message(message);
104 if(req_size < sizeof(struct StoreRequestMessage)) 112 if(NULL == record)
113 {
114 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Malformed store request from client\n");
115 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
116 return;
117 }
118 if(NULL == record->sub_system)
119 {
120 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sub system not supplied in client store request\n");
121 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
122 return;
123 }
124 if(NULL == record->peer)
105 { 125 {
106 GNUNET_break(0); 126 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Peer id not supplied in client store request\n");
107 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); 127 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
108 return; 128 return;
109 } 129 }
110 req = (struct StoreRequestMessage *)message; 130 if(NULL == record->key)
111 ss_size = ntohs(req->sub_system_size);
112 key_size = ntohs(req->key_size);
113 value_size = ntohs(req->value_size);
114 if(ss_size + key_size + value_size + sizeof(struct StoreRequestMessage)
115 != req_size)
116 { 131 {
117 GNUNET_break(0); 132 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Key not supplied in client store request\n");
118 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); 133 GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
119 return; 134 return;
120 } 135 }
121 sub_system = (char *)&req[1];
122 key = sub_system + ss_size;
123 value = key + key_size;
124 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Received a store request (size: %lu) for sub system `%s', peer `%s', key `%s'\n", 136 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Received a store request (size: %lu) for sub system `%s', peer `%s', key `%s'\n",
125 value_size, 137 record->value_size,
126 sub_system, 138 record->sub_system,
127 GNUNET_i2s (&req->peer), 139 GNUNET_i2s (record->peer),
128 key); 140 record->key);
129 if(GNUNET_OK == db->store_record(db->cls, 141 if(GNUNET_OK == db->store_record(db->cls,
130 sub_system, 142 record->sub_system,
131 &req->peer, 143 record->peer,
132 key, 144 record->key,
133 value, 145 record->value,
134 value_size)) 146 record->value_size))
135 { 147 {
136 response_type = GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_OK; 148 response_type = GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_OK;
137 } 149 }
@@ -161,6 +173,7 @@ run (void *cls,
161{ 173{
162 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 174 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
163 {&handle_store, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE, 0}, 175 {&handle_store, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE, 0},
176 {&handle_iterate, NULL, GNUNET_MESSAGE_TYPE_PEERSTORE_ITERATE, 0},
164 {NULL, NULL, 0, 0} 177 {NULL, NULL, 0, 0}
165 }; 178 };
166 char *database; 179 char *database;
diff --git a/src/peerstore/peerstore.h b/src/peerstore/peerstore.h
index 29e2ed866..521c5c11b 100644
--- a/src/peerstore/peerstore.h
+++ b/src/peerstore/peerstore.h
@@ -23,15 +23,18 @@
23 * @author Omar Tarabai 23 * @author Omar Tarabai
24 */ 24 */
25 25
26#ifndef PEERSTORE_H_
27#define PEERSTORE_H_
28
26#include "gnunet_peerstore_service.h" 29#include "gnunet_peerstore_service.h"
27 30
28 31
29GNUNET_NETWORK_STRUCT_BEGIN 32GNUNET_NETWORK_STRUCT_BEGIN
30 33
31/** 34/**
32 * Message carrying a PEERSTORE store request 35 * Message carrying a PEERSTORE record message
33 */ 36 */
34struct StoreRequestMessage 37struct StoreRecordMessage
35{ 38{
36 39
37 /** 40 /**
@@ -40,10 +43,9 @@ struct StoreRequestMessage
40 struct GNUNET_MessageHeader header; 43 struct GNUNET_MessageHeader header;
41 44
42 /** 45 /**
43 * Size of the sub_system string 46 * #GNUNET_YES if peer id value set, #GNUNET_NO otherwise
44 * Allocated at position 0 after this struct
45 */ 47 */
46 size_t sub_system_size; 48 uint16_t peer_set;
47 49
48 /** 50 /**
49 * Peer Identity 51 * Peer Identity
@@ -51,6 +53,12 @@ struct StoreRequestMessage
51 struct GNUNET_PeerIdentity peer; 53 struct GNUNET_PeerIdentity peer;
52 54
53 /** 55 /**
56 * Size of the sub_system string
57 * Allocated at position 0 after this struct
58 */
59 size_t sub_system_size;
60
61 /**
54 * Size of the key string 62 * Size of the key string
55 * Allocated at position 1 after this struct 63 * Allocated at position 1 after this struct
56 */ 64 */
@@ -70,3 +78,5 @@ struct StoreRequestMessage
70}; 78};
71 79
72GNUNET_NETWORK_STRUCT_END 80GNUNET_NETWORK_STRUCT_END
81
82#endif
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c
index fe6ff0fe3..68c171d52 100644
--- a/src/peerstore/peerstore_api.c
+++ b/src/peerstore/peerstore_api.c
@@ -26,6 +26,7 @@
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "peerstore.h" 28#include "peerstore.h"
29#include "peerstore_common.h"
29 30
30#define LOG(kind,...) GNUNET_log_from (kind, "peerstore-api",__VA_ARGS__) 31#define LOG(kind,...) GNUNET_log_from (kind, "peerstore-api",__VA_ARGS__)
31 32
@@ -209,11 +210,7 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
209 void *cont_cls) 210 void *cont_cls)
210{ 211{
211 struct GNUNET_PEERSTORE_StoreContext *sc; 212 struct GNUNET_PEERSTORE_StoreContext *sc;
212 struct StoreRequestMessage *srm; 213 struct StoreRecordMessage *srm;
213 size_t ss_size;
214 size_t key_size;
215 size_t request_size;
216 void *dummy;
217 214
218 LOG (GNUNET_ERROR_TYPE_DEBUG, 215 LOG (GNUNET_ERROR_TYPE_DEBUG,
219 "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n", 216 "Storing value (size: %lu) for subsytem `%s', peer `%s', key `%s'\n",
@@ -222,26 +219,12 @@ GNUNET_PEERSTORE_store (struct GNUNET_PEERSTORE_Handle *h,
222 sc->cont = cont; 219 sc->cont = cont;
223 sc->cont_cls = cont_cls; 220 sc->cont_cls = cont_cls;
224 sc->h = h; 221 sc->h = h;
225 ss_size = strlen(sub_system) + 1; 222 srm = PEERSTORE_create_record_message(sub_system,
226 key_size = strlen(key) + 1; 223 peer,
227 request_size = sizeof(struct StoreRequestMessage) + 224 key,
228 ss_size + 225 value,
229 key_size + 226 size,
230 size; 227 lifetime);
231 srm = GNUNET_malloc(request_size);
232 srm->header.size = htons(request_size);
233 srm->header.type = htons(GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
234 srm->key_size = htons(key_size);
235 srm->lifetime = lifetime;
236 srm->peer = *peer;
237 srm->sub_system_size = htons(ss_size);
238 srm->value_size = htons(size);
239 dummy = &srm[1];
240 memcpy(dummy, sub_system, ss_size);
241 dummy += ss_size;
242 memcpy(dummy, key, key_size);
243 dummy += key_size;
244 memcpy(dummy, value, size);
245 GNUNET_CLIENT_transmit_and_get_response(h->client, 228 GNUNET_CLIENT_transmit_and_get_response(h->client,
246 (const struct GNUNET_MessageHeader *)srm, 229 (const struct GNUNET_MessageHeader *)srm,
247 GNUNET_TIME_UNIT_FOREVER_REL, 230 GNUNET_TIME_UNIT_FOREVER_REL,
diff --git a/src/peerstore/peerstore_common.c b/src/peerstore/peerstore_common.c
new file mode 100644
index 000000000..f8c6862de
--- /dev/null
+++ b/src/peerstore/peerstore_common.c
@@ -0,0 +1,139 @@
1/*
2 This file is part of GNUnet
3 (C) 2012-2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20/**
21 * @file peerstore/peerstore_common.c
22 * @brief Helper peerstore functions
23 * @author Omar Tarabai
24 */
25
26#include "peerstore_common.h"
27
28/**
29 * Creates a record message ready to be sent
30 *
31 * @param sub_system sub system string
32 * @param peer Peer identity (can be NULL)
33 * @param key record key string (can be NULL)
34 * @param value record value BLOB (can be NULL)
35 * @param value_size record value size in bytes (set to 0 if value is NULL)
36 * @param lifetime relative time after which the record expires
37 * @return pointer to record message struct
38 */
39struct StoreRecordMessage *
40PEERSTORE_create_record_message(const char *sub_system,
41 const struct GNUNET_PeerIdentity *peer,
42 const char *key,
43 const void *value,
44 size_t value_size,
45 struct GNUNET_TIME_Relative lifetime)
46{
47 struct StoreRecordMessage *srm;
48 size_t ss_size;
49 size_t key_size;
50 size_t request_size;
51 void *dummy;
52
53 ss_size = strlen(sub_system) + 1;
54 if(NULL == key)
55 key_size = 0;
56 else
57 key_size = strlen(key) + 1;
58 request_size = sizeof(struct StoreRecordMessage) +
59 ss_size +
60 key_size +
61 value_size;
62 srm = GNUNET_malloc(request_size);
63 srm->header.size = htons(request_size);
64 srm->header.type = htons(GNUNET_MESSAGE_TYPE_PEERSTORE_STORE);
65 srm->key_size = htons(key_size);
66 srm->lifetime = lifetime;
67 if(NULL == peer)
68 srm->peer_set = htons(GNUNET_NO);
69 else
70 {
71 srm->peer_set = htons(GNUNET_YES);
72 srm->peer = *peer;
73 }
74 srm->sub_system_size = htons(ss_size);
75 srm->value_size = htons(value_size);
76 dummy = &srm[1];
77 memcpy(dummy, sub_system, ss_size);
78 dummy += ss_size;
79 memcpy(dummy, key, key_size);
80 dummy += key_size;
81 memcpy(dummy, value, value_size);
82 return srm;
83
84}
85
86/**
87 * Parses a message carrying a record
88 *
89 * @param message the actual message
90 * @return Pointer to record or NULL if error
91 */
92struct GNUNET_PEERSTORE_Record *
93PEERSTORE_parse_record_message(const struct GNUNET_MessageHeader *message)
94{
95 struct StoreRecordMessage *srm;
96 struct GNUNET_PEERSTORE_Record *record;
97 uint16_t req_size;
98 uint16_t ss_size;
99 uint16_t key_size;
100 uint16_t value_size;
101 char *dummy;
102
103 req_size = ntohs(message->size);
104 if(req_size < sizeof(struct StoreRecordMessage))
105 return NULL;
106 srm = (struct StoreRecordMessage *)message;
107 ss_size = ntohs(srm->sub_system_size);
108 key_size = ntohs(srm->key_size);
109 value_size = ntohs(srm->value_size);
110 if(ss_size + key_size + value_size + sizeof(struct StoreRecordMessage)
111 != req_size)
112 return NULL;
113 record = GNUNET_new(struct GNUNET_PEERSTORE_Record);
114 if(GNUNET_YES == ntohs(srm->peer_set))
115 {
116 record->peer = GNUNET_new(struct GNUNET_PeerIdentity);
117 memcpy(record->peer, &srm->peer, sizeof(struct GNUNET_PeerIdentity));
118 }
119 record->lifetime = srm->lifetime;
120 dummy = (char *)&srm[1];
121 if(ss_size > 0)
122 {
123 record->sub_system = GNUNET_strdup(dummy);
124 dummy += ss_size;
125 }
126 if(key_size > 0)
127 {
128 record->key = GNUNET_strdup(dummy);
129 dummy += key_size;
130 }
131 if(value_size > 0)
132 {
133 record->value = GNUNET_malloc(value_size);
134 memcpy(record->value, dummy, value_size);
135 }
136 record->value_size = value_size;
137
138 return record;
139}
diff --git a/src/peerstore/peerstore_common.h b/src/peerstore/peerstore_common.h
new file mode 100644
index 000000000..93fb9931b
--- /dev/null
+++ b/src/peerstore/peerstore_common.h
@@ -0,0 +1,93 @@
1/*
2 This file is part of GNUnet
3 (C)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/**
22 * @file peerstore/peerstore_common.h
23 * @brief Helper peerstore functions
24 * @author Omar Tarabai
25 */
26
27#include "peerstore.h"
28
29/**
30 * PEERSTORE single record
31 */
32struct GNUNET_PEERSTORE_Record
33{
34
35 /**
36 * Responsible sub system string
37 */
38 char *sub_system;
39
40 /**
41 * Peer Identity
42 */
43 struct GNUNET_PeerIdentity *peer;
44
45 /**
46 * Record key string
47 */
48 char *key;
49
50 /**
51 * Record value BLOB
52 */
53 void *value;
54
55 /**
56 * Size of value BLOB
57 */
58 size_t value_size;
59
60 /**
61 * Lifetime of record
62 */
63 struct GNUNET_TIME_Relative lifetime;
64
65};
66
67/**
68 * Creates a record message ready to be sent
69 *
70 * @param sub_system sub system string
71 * @param peer Peer identity (can be NULL)
72 * @param key record key string (can be NULL)
73 * @param value record value BLOB (can be NULL)
74 * @param value_size record value size in bytes (set to 0 if value is NULL)
75 * @param lifetime relative time after which the record expires
76 * @return pointer to record message struct
77 */
78struct StoreRecordMessage *
79PEERSTORE_create_record_message(const char *sub_system,
80 const struct GNUNET_PeerIdentity *peer,
81 const char *key,
82 const void *value,
83 size_t value_size,
84 struct GNUNET_TIME_Relative lifetime);
85
86/**
87 * Parses a message carrying a record
88 *
89 * @param message the actual message
90 * @return Pointer to record or NULL if error
91 */
92struct GNUNET_PEERSTORE_Record *
93PEERSTORE_parse_record_message(const struct GNUNET_MessageHeader *message);
diff --git a/src/peerstore/plugin_peerstore_sqlite.c b/src/peerstore/plugin_peerstore_sqlite.c
index ac6d30931..10ab17650 100644
--- a/src/peerstore/plugin_peerstore_sqlite.c
+++ b/src/peerstore/plugin_peerstore_sqlite.c
@@ -90,101 +90,67 @@ struct Plugin
90 /** 90 /**
91 * Precompiled SQL for selecting from peerstoredata 91 * Precompiled SQL for selecting from peerstoredata
92 */ 92 */
93 sqlite3_stmt *select_peerstoredata_by_ss; 93 sqlite3_stmt *select_peerstoredata_by_key;
94 94
95 /** 95 /**
96 * Precompiled SQL for selecting from peerstoredata 96 * Precompiled SQL for selecting from peerstoredata
97 */ 97 */
98 sqlite3_stmt *select_peerstoredata_by_both; 98 sqlite3_stmt *select_peerstoredata_by_all;
99 99
100}; 100};
101 101
102/** 102/**
103 * The given 'sqlite' statement has been prepared to be run.
104 * It will return a record which should be given to the iterator.
105 * Runs the statement and parses the returned record.
106 *
107 * @param plugin plugin context
108 * @param stmt to run (and then clean up)
109 * @param iter iterator to call with the result
110 * @param iter_cls closure for @a iter
111 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
112 */
113static int
114get_record_and_call_iterator (struct Plugin *plugin,
115 sqlite3_stmt *stmt,
116 GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls)
117{
118 int ret;
119 int sret;
120 const struct GNUNET_PeerIdentity *pid;
121 const char *sub_system;
122 const void *value;
123 size_t value_size;
124
125 ret = GNUNET_NO;
126 if (SQLITE_ROW == (sret = sqlite3_step (stmt)))
127 {
128 pid = sqlite3_column_blob(stmt, 0);
129 sub_system = (const char*) sqlite3_column_text(stmt, 1);
130 value = sqlite3_column_blob(stmt, 2);
131 value_size = sqlite3_column_bytes(stmt, 2);
132 if (NULL != iter)
133 iter (iter_cls, pid, sub_system, value, value_size);
134 ret = GNUNET_YES;
135 }
136 else
137 {
138 if (SQLITE_DONE != sret)
139 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
140 }
141 if (SQLITE_OK != sqlite3_reset (stmt))
142 LOG_SQLITE (plugin,
143 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
144 "sqlite3_reset");
145 return ret;
146
147}
148
149/**
150 * Iterate over the records given an optional peer id 103 * Iterate over the records given an optional peer id
151 * and/or sub system. 104 * and/or key.
152 * 105 *
153 * @param cls closure (internal context for the plugin) 106 * @param cls closure (internal context for the plugin)
107 * @param sub_system name of sub system
154 * @param peer Peer identity (can be NULL) 108 * @param peer Peer identity (can be NULL)
155 * @param sub_system name of sub system (can be NULL) 109 * @param key entry key string (can be NULL)
156 * @param iter function to call with the result 110 * @param iter function to call with the result
157 * @param iter_cls closure for @a iter 111 * @param iter_cls closure for @a iter
158 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error 112 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
159 */ 113 */
160static int 114static int
161peerstore_sqlite_iterate_records (void *cls, 115peerstore_sqlite_iterate_records (void *cls,
162 const struct GNUNET_PeerIdentity *peer,
163 const char *sub_system, 116 const char *sub_system,
117 const struct GNUNET_PeerIdentity *peer,
118 const char *key,
164 GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls) 119 GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls)
165{ 120{
166 struct Plugin *plugin = cls; 121 struct Plugin *plugin = cls;
167 sqlite3_stmt *stmt; 122 sqlite3_stmt *stmt;
168 int err = 0; 123 int err = 0;
124 int sret;
125 const char *ret_sub_system;
126 const struct GNUNET_PeerIdentity *ret_peer;
127 const char *ret_key;
128 const void *ret_value;
129 size_t ret_value_size;
169 130
170 if(NULL == sub_system && NULL == peer) 131 if(NULL == peer && NULL == key)
132 {
171 stmt = plugin->select_peerstoredata; 133 stmt = plugin->select_peerstoredata;
172 else if(NULL == sub_system) 134 err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC));
135 }
136 else if(NULL == key)
173 { 137 {
174 stmt = plugin->select_peerstoredata_by_pid; 138 stmt = plugin->select_peerstoredata_by_pid;
175 err = (SQLITE_OK != sqlite3_bind_blob(stmt, 1, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC)); 139 err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC))
140 || (SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC));
176 } 141 }
177 else if(NULL == peer) 142 else if(NULL == peer)
178 { 143 {
179 stmt = plugin->select_peerstoredata_by_ss; 144 stmt = plugin->select_peerstoredata_by_key;
180 err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)); 145 err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC))
146 || (SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, SQLITE_STATIC));
181 } 147 }
182 else 148 else
183 { 149 {
184 stmt = plugin->select_peerstoredata_by_both; 150 stmt = plugin->select_peerstoredata_by_all;
185 err = 151 err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, strlen(sub_system) + 1, SQLITE_STATIC))
186 (SQLITE_OK != sqlite3_bind_blob(stmt, 1, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC)) 152 || (SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct GNUNET_PeerIdentity), SQLITE_STATIC))
187 || (SQLITE_OK != sqlite3_bind_text(stmt, 2, sub_system, strlen(sub_system) + 1, SQLITE_STATIC)); 153 || (SQLITE_OK != sqlite3_bind_text(stmt, 3, key, strlen(key) + 1, SQLITE_STATIC));
188 } 154 }
189 155
190 if (err) 156 if (err)
@@ -197,7 +163,31 @@ peerstore_sqlite_iterate_records (void *cls,
197 "sqlite3_reset"); 163 "sqlite3_reset");
198 return GNUNET_SYSERR; 164 return GNUNET_SYSERR;
199 } 165 }
200 return get_record_and_call_iterator (plugin, stmt, iter, iter_cls); 166 while (SQLITE_ROW == (sret = sqlite3_step (stmt)))
167 {
168 ret_sub_system = (const char *)sqlite3_column_text(stmt, 0);
169 ret_peer = sqlite3_column_blob(stmt, 1);
170 ret_key = (const char *)sqlite3_column_text(stmt, 2);
171 ret_value = sqlite3_column_blob(stmt, 3);
172 ret_value_size = sqlite3_column_bytes(stmt, 3);
173 if (NULL != iter)
174 iter (iter_cls, ret_sub_system, ret_peer, ret_key, ret_value, ret_value_size);
175 }
176 if (SQLITE_DONE != sret)
177 {
178 LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
179 err = 1;
180 }
181 if (SQLITE_OK != sqlite3_reset (stmt))
182 {
183 LOG_SQLITE (plugin,
184 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
185 "sqlite3_reset");
186 err = 1;
187 }
188 if(err)
189 return GNUNET_SYSERR;
190 return GNUNET_OK;
201} 191}
202 192
203/** 193/**
@@ -362,17 +352,25 @@ database_setup (struct Plugin *plugin)
362 "INSERT INTO peerstoredata (sub_system, peer_id, key, value) VALUES (?,?,?,?);", 352 "INSERT INTO peerstoredata (sub_system, peer_id, key, value) VALUES (?,?,?,?);",
363 &plugin->insert_peerstoredata); 353 &plugin->insert_peerstoredata);
364 sql_prepare(plugin->dbh, 354 sql_prepare(plugin->dbh,
365 "SELECT peer_id, sub_system, value FROM peerstoredata", 355 "SELECT peer_id, sub_system, value FROM peerstoredata"
356 " WHERE sub_system = ?",
366 &plugin->select_peerstoredata); 357 &plugin->select_peerstoredata);
367 sql_prepare(plugin->dbh, 358 sql_prepare(plugin->dbh,
368 "SELECT peer_id, sub_system, value FROM peerstoredata WHERE peer_id = ?", 359 "SELECT peer_id, sub_system, value FROM peerstoredata"
360 " WHERE sub_system = ?"
361 " AND peer_id = ?",
369 &plugin->select_peerstoredata_by_pid); 362 &plugin->select_peerstoredata_by_pid);
370 sql_prepare(plugin->dbh, 363 sql_prepare(plugin->dbh,
371 "SELECT peer_id, sub_system, value FROM peerstoredata WHERE sub_system = ?", 364 "SELECT peer_id, sub_system, value FROM peerstoredata"
372 &plugin->select_peerstoredata_by_ss); 365 " WHERE sub_system = ?"
366 " AND key = ?",
367 &plugin->select_peerstoredata_by_key);
373 sql_prepare(plugin->dbh, 368 sql_prepare(plugin->dbh,
374 "SELECT peer_id, sub_system, value FROM peerstoredata WHERE peer_id = ? AND sub_system = ?", 369 "SELECT peer_id, sub_system, value FROM peerstoredata"
375 &plugin->select_peerstoredata_by_both); 370 " WHERE sub_system = ?"
371 " AND peer_id = ?"
372 " AND key = ?",
373 &plugin->select_peerstoredata_by_all);
376 374
377 return GNUNET_OK; 375 return GNUNET_OK;
378} 376}