aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-09-22 00:13:52 +0900
committerMartin Schanzenbach <schanzen@gnunet.org>2022-09-22 00:31:07 +0900
commite1d8213bb3264ef384af84d01b0ad05f7911f829 (patch)
tree40fc2beacf87802d04dde29bae848501c555d1f3
parentc50fba92d14a20c4321768c26b3dd6e417c46f23 (diff)
downloadgnunet-e1d8213bb3264ef384af84d01b0ad05f7911f829.tar.gz
gnunet-e1d8213bb3264ef384af84d01b0ad05f7911f829.zip
NAMESTORE: Start transactional API
-rw-r--r--src/include/gnunet_namestore_plugin.h52
-rw-r--r--src/namestore/plugin_namestore_sqlite.c63
2 files changed, 69 insertions, 46 deletions
diff --git a/src/include/gnunet_namestore_plugin.h b/src/include/gnunet_namestore_plugin.h
index 9301c29fe..82bac1f9e 100644
--- a/src/include/gnunet_namestore_plugin.h
+++ b/src/include/gnunet_namestore_plugin.h
@@ -160,63 +160,31 @@ struct GNUNET_NAMESTORE_PluginFunctions
160 * Start a transaction in the database 160 * Start a transaction in the database
161 * 161 *
162 * @param cls closure (internal context for the plugin) 162 * @param cls closure (internal context for the plugin)
163 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error 163 * @param emsg message. On error, string will be allocated and must be freed.
164 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
164 */ 165 */
165 enum GNUNET_GenericReturnValue 166 enum GNUNET_GenericReturnValue
166 (*transaction_begin) (void *cls); 167 (*transaction_begin) (void *cls, char **emsg);
167 168
168 /** 169 /**
169 * Abort a transaction in the database 170 * Abort and roll back a transaction in the database
170 * 171 *
171 * @param cls closure (internal context for the plugin) 172 * @param cls closure (internal context for the plugin)
172 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error 173 * @param emsg message. On error, string will be allocated and must be freed.
174 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
173 */ 175 */
174 enum GNUNET_GenericReturnValue 176 enum GNUNET_GenericReturnValue
175 (*transaction_abort) (void *cls); 177 (*transaction_rollback) (void *cls, char **emsg);
176 178
177 /** 179 /**
178 * Commit a transaction in the database 180 * Commit a transaction in the database
179 * 181 *
180 * @param cls closure (internal context for the plugin) 182 * @param cls closure (internal context for the plugin)
181 * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error 183 * @param emsg message. On error, string will be allocated and must be freed.
184 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
182 */ 185 */
183 enum GNUNET_GenericReturnValue 186 enum GNUNET_GenericReturnValue
184 (*transaction_commit) (void *cls); 187 (*transaction_commit) (void *cls, char **emsg);
185
186 /**
187 * Replace a record in the datastore for which we are the authority.
188 * Removes any existing record in the same zone with the same name.
189 *
190 * @param cls closure (internal context for the plugin)
191 * @param zone private key of the zone
192 * @param label name of the record in the zone
193 * @param rd_count number of entries in @a rd array, 0 to delete all records
194 * @param rd array of records with data to store
195 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
196 */
197 int
198 (*replace_records) (void *cls,
199 const struct GNUNET_IDENTITY_PrivateKey *zone,
200 const char *label,
201 unsigned int rd_count,
202 const struct GNUNET_GNSRECORD_Data *rd);
203
204 /**
205 * Lookup records in the datastore for which we are the authority.
206 *
207 * @param cls closure (internal context for the plugin)
208 * @param zone private key of the zone
209 * @param label name of the record in the zone
210 * @param iter function to call with the result
211 * @param iter_cls closure for @a iter
212 * @return #GNUNET_OK on success, #GNUNET_NO for no results, else #GNUNET_SYSERR
213 */
214 int
215 (*select_records) (void *cls,
216 const struct GNUNET_IDENTITY_PrivateKey *zone,
217 const char *label,
218 GNUNET_NAMESTORE_RecordIterator iter,
219 void *iter_cls);
220 188
221}; 189};
222 190
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c
index 0b3aac84f..f2017b695 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -331,8 +331,8 @@ namestore_sqlite_store_records (void *cls,
331 for (unsigned int i = 0; i < rd_count; i++) 331 for (unsigned int i = 0; i < rd_count; i++)
332 { 332 {
333 LOG (GNUNET_ERROR_TYPE_DEBUG, 333 LOG (GNUNET_ERROR_TYPE_DEBUG,
334 "Checking if `%d' is zonekey type\n", 334 "Checking if `%d' is zonekey type\n",
335 rd[i].record_type); 335 rd[i].record_type);
336 336
337 if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type)) 337 if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type))
338 { 338 {
@@ -342,8 +342,8 @@ namestore_sqlite_store_records (void *cls,
342 rd[i].record_type, 342 rd[i].record_type,
343 &pkey)); 343 &pkey));
344 LOG (GNUNET_ERROR_TYPE_DEBUG, 344 LOG (GNUNET_ERROR_TYPE_DEBUG,
345 "Storing delegation zone record value `%s'\n", 345 "Storing delegation zone record value `%s'\n",
346 GNUNET_GNSRECORD_z2s (&pkey)); 346 GNUNET_GNSRECORD_z2s (&pkey));
347 347
348 break; 348 break;
349 } 349 }
@@ -740,6 +740,58 @@ namestore_sqlite_zone_to_name (void *cls,
740 iter_cls); 740 iter_cls);
741} 741}
742 742
743/**
744 * Begin a transaction for a client.
745 * This locks the database. SQLite is unable to discern between different
746 * rows with a specific zone key but the API looks like this anyway.
747 * https://www.sqlite.org/lang_transaction.html
748 *
749 * @param cls closure (internal context for the plugin)
750 * @param emsg error message set of return code is #GNUNET_SYSERR
751 * @return #GNUNET_OK on success, #GNUNET_SYSERR if transaction cannot be started.
752 */
753static enum GNUNET_GenericReturnValue
754namestore_sqlite_transaction_begin (void *cls,
755 char **emsg)
756{
757 struct Plugin *plugin = cls;
758 return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "BEGIN TRANSACTION;", NULL,
759 NULL, emsg)) ? GNUNET_SYSERR : GNUNET_OK;
760}
761
762/**
763 * Commit a transaction for a client.
764 * This releases the lock on the database.
765 *
766 * @param cls closure (internal context for the plugin)
767 * @param emsg error message set of return code is #GNUNET_SYSERR
768 * @return #GNUNET_OK on success, #GNUNET_SYSERR if transaction cannot be started.
769 */
770static enum GNUNET_GenericReturnValue
771namestore_sqlite_transaction_rollback (void *cls,
772 char **emsg)
773{
774 struct Plugin *plugin = cls;
775 return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "ROLLBACK;", NULL,
776 NULL, emsg)) ? GNUNET_SYSERR : GNUNET_OK;
777}
778
779/**
780 * Roll back a transaction for a client.
781 * This releases the lock on the database.
782 *
783 * @param cls closure (internal context for the plugin)
784 * @param emsg error message set of return code is #GNUNET_SYSERR
785 * @return #GNUNET_OK on success, #GNUNET_SYSERR if transaction cannot be started.
786 */
787static enum GNUNET_GenericReturnValue
788namestore_sqlite_transaction_commit (void *cls,
789 char **emsg)
790{
791 struct Plugin *plugin = cls;
792 return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "END TRANSACTION;", NULL,
793 NULL, emsg)) ? GNUNET_SYSERR : GNUNET_OK;
794}
743 795
744/** 796/**
745 * Entry point for the plugin. 797 * Entry point for the plugin.
@@ -771,6 +823,9 @@ libgnunet_plugin_namestore_sqlite_init (void *cls)
771 api->iterate_records = &namestore_sqlite_iterate_records; 823 api->iterate_records = &namestore_sqlite_iterate_records;
772 api->zone_to_name = &namestore_sqlite_zone_to_name; 824 api->zone_to_name = &namestore_sqlite_zone_to_name;
773 api->lookup_records = &namestore_sqlite_lookup_records; 825 api->lookup_records = &namestore_sqlite_lookup_records;
826 api->transaction_begin = &namestore_sqlite_transaction_begin;
827 api->transaction_commit = &namestore_sqlite_transaction_commit;
828 api->transaction_rollback = &namestore_sqlite_transaction_rollback;
774 LOG (GNUNET_ERROR_TYPE_INFO, 829 LOG (GNUNET_ERROR_TYPE_INFO,
775 _ ("Sqlite database running\n")); 830 _ ("Sqlite database running\n"));
776 return api; 831 return api;