From e97190eb74ebb4abc0f5958ba99f838f4766b1cf Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 16 Nov 2022 13:57:32 +0100 Subject: add versioning.sql --- po/de.po | 12 +- po/es.po | 40 +++--- po/fr.po | 12 +- po/it.po | 12 +- po/sr.po | 16 +-- po/sv.po | 28 ++--- po/vi.po | 16 +-- po/zh_CN.po | 12 +- src/fs/Makefile.am | 2 +- src/include/gnunet_pq_lib.h | 33 +++++ src/pq/Makefile.am | 9 ++ src/pq/pq_connect.c | 2 + src/pq/pq_eval.c | 10 +- src/pq/versioning.sql | 293 ++++++++++++++++++++++++++++++++++++++++++++ src/util/crypto_crc.c | 5 +- 15 files changed, 419 insertions(+), 83 deletions(-) create mode 100644 src/pq/versioning.sql diff --git a/po/de.po b/po/de.po index 8b84b7407..f7ede3cf0 100644 --- a/po/de.po +++ b/po/de.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: gnunet 0.10.1\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2022-11-04 14:22+0900\n" +"POT-Creation-Date: 2022-11-14 08:54+0100\n" "PO-Revision-Date: 2015-03-08 16:16+0100\n" "Last-Translator: Mario Blättermann \n" "Language-Team: German \n" @@ -4627,23 +4627,23 @@ msgstr "" msgid "Maintain egos" msgstr "" -#: src/identity/gnunet-service-identity.c:685 -#: src/identity/gnunet-service-identity.c:804 +#: src/identity/gnunet-service-identity.c:687 +#: src/identity/gnunet-service-identity.c:806 #, fuzzy, c-format msgid "Failed to write subsystem default identifier map to `%s'.\n" msgstr "Fehler beim Aktualisieren der Daten des Moduls `%s'\n" -#: src/identity/gnunet-service-identity.c:919 +#: src/identity/gnunet-service-identity.c:921 #, fuzzy, c-format msgid "Failed to parse ego information in `%s'\n" msgstr "Fehler beim Parsen der Gerätedaten von `%s' bei %s:%d.\n" -#: src/identity/gnunet-service-identity.c:977 +#: src/identity/gnunet-service-identity.c:979 #, fuzzy, c-format msgid "Failed to parse subsystem identity configuration file `%s'\n" msgstr "Fehler beim Speichern der Konfigurationsdatei `%s':" -#: src/identity/gnunet-service-identity.c:986 +#: src/identity/gnunet-service-identity.c:988 #, fuzzy, c-format msgid "Failed to create directory `%s' for storing egos\n" msgstr "Dateiformat fehlerhaft (kein GNUnet Verzeichnis?)\n" diff --git a/po/es.po b/po/es.po index 52d0f2533..9e5f78349 100644 --- a/po/es.po +++ b/po/es.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gnunet 0.9.5a\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2022-11-04 14:22+0900\n" +"POT-Creation-Date: 2022-11-14 08:54+0100\n" "PO-Revision-Date: 2013-02-23 17:50+0100\n" "Last-Translator: Miguel Ángel Arruga Vivas \n" "Language-Team: Spanish \n" @@ -4786,24 +4786,24 @@ msgstr "" msgid "Maintain egos" msgstr "" -#: src/identity/gnunet-service-identity.c:685 -#: src/identity/gnunet-service-identity.c:804 +#: src/identity/gnunet-service-identity.c:687 +#: src/identity/gnunet-service-identity.c:806 #, fuzzy, c-format msgid "Failed to write subsystem default identifier map to `%s'.\n" msgstr "" "Se produjo un fallo al obtener los identificadores de fichero para «%s»\n" -#: src/identity/gnunet-service-identity.c:919 +#: src/identity/gnunet-service-identity.c:921 #, fuzzy, c-format msgid "Failed to parse ego information in `%s'\n" msgstr "Se produjo un fallo al procesar la identidad del par «%s»\n" -#: src/identity/gnunet-service-identity.c:977 +#: src/identity/gnunet-service-identity.c:979 #, fuzzy, c-format msgid "Failed to parse subsystem identity configuration file `%s'\n" msgstr "Se produjo un fallo al borrar el fichero de configuración %s\n" -#: src/identity/gnunet-service-identity.c:986 +#: src/identity/gnunet-service-identity.c:988 #, fuzzy, c-format msgid "Failed to create directory `%s' for storing egos\n" msgstr "Se produjo un fallo al leer el directorio «%s»\n" @@ -11614,8 +11614,8 @@ msgstr "¡Se produjo un fallo al conectar con el almacén de nombres!\n" #~ "%llu, omitiendo bytes.\n" #~ msgid "" -#~ "Syntax error in topology specification at offset %llu, skipping bytes " -#~ "`%s'.\n" +#~ "Syntax error in topology specification at offset %llu, skipping bytes `" +#~ "%s'.\n" #~ msgstr "" #~ "Error de sintaxis en la especificación de topología en el desplazamiento " #~ "%llu, omitiendo bytes «%s».\n" @@ -13170,10 +13170,10 @@ msgstr "¡Se produjo un fallo al conectar con el almacén de nombres!\n" #~ "You can specify a hostname, GNUnet will then use DNS to resolve it.\n" #~ "If in doubt, leave this empty." #~ msgstr "" -#~ "Si tu proveedor siempre te asigna la misma dirección IP (una IP " -#~ "\"estática\") introducela en el campo \"Dirección IP\". Si tu dirección " -#~ "IP cambia pero hay un nombre de dominio que siempre apunta a tu dirección " -#~ "IP actual (\"DNS dinámica\"), puedes introducirlo allí también.\n" +#~ "Si tu proveedor siempre te asigna la misma dirección IP (una IP \"estática" +#~ "\") introducela en el campo \"Dirección IP\". Si tu dirección IP cambia " +#~ "pero hay un nombre de dominio que siempre apunta a tu dirección IP actual " +#~ "(\"DNS dinámica\"), puedes introducirlo allí también.\n" #~ "En caso de duda deja el campo en blanco. GNUnet intentará determinar tu " #~ "dirección IP" @@ -14540,8 +14540,8 @@ msgstr "¡Se produjo un fallo al conectar con el almacén de nombres!\n" #~ "SNAT, a un router o a un \"cortafuegos de hardware\" y otros ordenadores " #~ "no pueden conectar con tu ordenador marca la última opción en ésta " #~ "página. Déjala sin marcar en conexiones directas a través de modems, " -#~ "tarjetas de RDSI y DNAT (también conocido como \"seguimiento de " -#~ "puertos\")." +#~ "tarjetas de RDSI y DNAT (también conocido como \"seguimiento de puertos" +#~ "\")." #~ msgid "Computer cannot receive inbound connections (SNAT/Firewall)" #~ msgstr "" @@ -14978,10 +14978,10 @@ msgstr "¡Se produjo un fallo al conectar con el almacén de nombres!\n" #~ "\n" #~ "Si tu estás conectado a Internet a través de otro ordenador haciendo " #~ "SNAT, un router o un \"cortafuegos de hardware\" y otros ordenadores no " -#~ "pueden conectarse al tuyo a través de Internet directamente, responde " -#~ "\"si\" aquí. Responde \"no\" en conexiones directas a través de módems, " -#~ "tarjetas de RDSI y DNAT (también conocido como \"seguimiento de " -#~ "puertos\")." +#~ "pueden conectarse al tuyo a través de Internet directamente, responde \"si" +#~ "\" aquí. Responde \"no\" en conexiones directas a través de módems, " +#~ "tarjetas de RDSI y DNAT (también conocido como \"seguimiento de puertos" +#~ "\")." #, fuzzy #~ msgid "Run gnunetd as this user." @@ -15234,8 +15234,8 @@ msgstr "¡Se produjo un fallo al conectar con el almacén de nombres!\n" #~ msgstr "Recibido mensaje UDP no válido del %u.%u.%u.%u:%u, omitiendo.\n" #~ msgid "" -#~ "Configuration file must specify directory for storing FS data in section " -#~ "`%s' under `%s'.\n" +#~ "Configuration file must specify directory for storing FS data in section `" +#~ "%s' under `%s'.\n" #~ msgstr "" #~ "El fichero de configuración debe especificar el directorio para almacenar " #~ "los datos FS en la sección '%s' bajo '%s'.\n" diff --git a/po/fr.po b/po/fr.po index 35094e2f6..de9c5474e 100644 --- a/po/fr.po +++ b/po/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gnunet 0.10.1\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2022-11-04 14:22+0900\n" +"POT-Creation-Date: 2022-11-14 08:54+0100\n" "PO-Revision-Date: 2021-11-21 00:53+0100\n" "Last-Translator: Stéphane Aulery \n" "Language-Team: French \n" @@ -4441,23 +4441,23 @@ msgstr "" msgid "Maintain egos" msgstr "" -#: src/identity/gnunet-service-identity.c:685 -#: src/identity/gnunet-service-identity.c:804 +#: src/identity/gnunet-service-identity.c:687 +#: src/identity/gnunet-service-identity.c:806 #, c-format msgid "Failed to write subsystem default identifier map to `%s'.\n" msgstr "" -#: src/identity/gnunet-service-identity.c:919 +#: src/identity/gnunet-service-identity.c:921 #, c-format msgid "Failed to parse ego information in `%s'\n" msgstr "" -#: src/identity/gnunet-service-identity.c:977 +#: src/identity/gnunet-service-identity.c:979 #, c-format msgid "Failed to parse subsystem identity configuration file `%s'\n" msgstr "" -#: src/identity/gnunet-service-identity.c:986 +#: src/identity/gnunet-service-identity.c:988 #, c-format msgid "Failed to create directory `%s' for storing egos\n" msgstr "" diff --git a/po/it.po b/po/it.po index 24fc982b6..36257c0a3 100644 --- a/po/it.po +++ b/po/it.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gnunet 0.10.1\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2022-11-04 14:22+0900\n" +"POT-Creation-Date: 2022-11-14 08:54+0100\n" "PO-Revision-Date: 2019-10-16 11:00+0200\n" "Last-Translator: Sebastiano Pistore \n" "Language-Team: Italian \n" @@ -4466,23 +4466,23 @@ msgstr "" msgid "Maintain egos" msgstr "" -#: src/identity/gnunet-service-identity.c:685 -#: src/identity/gnunet-service-identity.c:804 +#: src/identity/gnunet-service-identity.c:687 +#: src/identity/gnunet-service-identity.c:806 #, c-format msgid "Failed to write subsystem default identifier map to `%s'.\n" msgstr "" -#: src/identity/gnunet-service-identity.c:919 +#: src/identity/gnunet-service-identity.c:921 #, c-format msgid "Failed to parse ego information in `%s'\n" msgstr "" -#: src/identity/gnunet-service-identity.c:977 +#: src/identity/gnunet-service-identity.c:979 #, c-format msgid "Failed to parse subsystem identity configuration file `%s'\n" msgstr "" -#: src/identity/gnunet-service-identity.c:986 +#: src/identity/gnunet-service-identity.c:988 #, c-format msgid "Failed to create directory `%s' for storing egos\n" msgstr "" diff --git a/po/sr.po b/po/sr.po index 5e09a76d6..cc36d9b3a 100644 --- a/po/sr.po +++ b/po/sr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gnunet-0.10.1\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2022-11-04 14:22+0900\n" +"POT-Creation-Date: 2022-11-14 08:54+0100\n" "PO-Revision-Date: 2020-10-23 18:39+0200\n" "Last-Translator: Мирослав Николић \n" "Language-Team: Serbian <(nothing)>\n" @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Bugs: Report translation errors to the Language-Team address.\n" #: src/abd/gnunet-abd.c:392 src/namestore/gnunet-namestore-zonefile.c:193 @@ -4649,24 +4649,24 @@ msgstr "" msgid "Maintain egos" msgstr "Одржава егое" -#: src/identity/gnunet-service-identity.c:685 -#: src/identity/gnunet-service-identity.c:804 +#: src/identity/gnunet-service-identity.c:687 +#: src/identity/gnunet-service-identity.c:806 #, c-format msgid "Failed to write subsystem default identifier map to `%s'.\n" msgstr "Нисам успео да запишем основну мапу одредника подсистема у „%s“.\n" -#: src/identity/gnunet-service-identity.c:919 +#: src/identity/gnunet-service-identity.c:921 #, c-format msgid "Failed to parse ego information in `%s'\n" msgstr "Нисам успео да обрадим податке егоа у „%s“\n" -#: src/identity/gnunet-service-identity.c:977 +#: src/identity/gnunet-service-identity.c:979 #, c-format msgid "Failed to parse subsystem identity configuration file `%s'\n" msgstr "" "Нисам успео да обрадим датотеку подешавања идентитета субсистема „%s“\n" -#: src/identity/gnunet-service-identity.c:986 +#: src/identity/gnunet-service-identity.c:988 #, c-format msgid "Failed to create directory `%s' for storing egos\n" msgstr "Нисам успео да направим директоријум „%s“ за смештајне егое\n" diff --git a/po/sv.po b/po/sv.po index 480e32615..c5ac16014 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GNUnet 0.7.0b\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2022-11-04 14:22+0900\n" +"POT-Creation-Date: 2022-11-14 08:54+0100\n" "PO-Revision-Date: 2006-01-21 17:16+0100\n" "Last-Translator: Daniel Nylander \n" "Language-Team: Swedish \n" @@ -4645,23 +4645,23 @@ msgstr "" msgid "Maintain egos" msgstr "" -#: src/identity/gnunet-service-identity.c:685 -#: src/identity/gnunet-service-identity.c:804 +#: src/identity/gnunet-service-identity.c:687 +#: src/identity/gnunet-service-identity.c:806 #, fuzzy, c-format msgid "Failed to write subsystem default identifier map to `%s'.\n" msgstr "Misslyckades att läsa kompislista från \"%s\"\n" -#: src/identity/gnunet-service-identity.c:919 +#: src/identity/gnunet-service-identity.c:921 #, fuzzy, c-format msgid "Failed to parse ego information in `%s'\n" msgstr "Misslyckades att läsa kompislista från \"%s\"\n" -#: src/identity/gnunet-service-identity.c:977 +#: src/identity/gnunet-service-identity.c:979 #, fuzzy, c-format msgid "Failed to parse subsystem identity configuration file `%s'\n" msgstr "Kunde inte spara konfigurationsfil \"%s\":" -#: src/identity/gnunet-service-identity.c:986 +#: src/identity/gnunet-service-identity.c:988 #, fuzzy, c-format msgid "Failed to create directory `%s' for storing egos\n" msgstr "Misslyckades att läsa kompislista från \"%s\"\n" @@ -7683,15 +7683,15 @@ msgstr "Testar transport(er) %s\n" #, fuzzy, c-format msgid "Specific IPv4 address `%s' in configuration file is invalid!\n" msgstr "" -"Du måste ange ett positivt nummer för \"%s\" i konfigurationen i sektion " -"\"%s\".\n" +"Du måste ange ett positivt nummer för \"%s\" i konfigurationen i sektion \"%s" +"\".\n" #: src/transport/plugin_transport_http_server.c:3133 #, fuzzy, c-format msgid "Specific IPv6 address `%s' in configuration file is invalid!\n" msgstr "" -"Du måste ange ett positivt nummer för \"%s\" i konfigurationen i sektion " -"\"%s\".\n" +"Du måste ange ett positivt nummer för \"%s\" i konfigurationen i sektion \"%s" +"\".\n" #: src/transport/plugin_transport_http_server.c:3208 #, fuzzy, c-format @@ -9056,8 +9056,8 @@ msgid "" "Missing `%s' or numeric IP address for `%s' of `%s' in configuration, DNS " "resolution will be unavailable.\n" msgstr "" -"Du måste ange ett positivt nummer för \"%s\" i konfigurationen i sektion " -"\"%s\".\n" +"Du måste ange ett positivt nummer för \"%s\" i konfigurationen i sektion \"%s" +"\".\n" #: src/util/resolver_api.c:887 #, fuzzy, c-format @@ -12391,8 +12391,8 @@ msgstr "Misslyckades att ansluta till gnunetd.\n" #~ msgstr "Kunde inte slå upp namnet för SMTP-server \"%s\": %s" #~ msgid "" -#~ "You must specify the name of a pipe for the SMTP transport in section " -#~ "`%s' under `%s'.\n" +#~ "You must specify the name of a pipe for the SMTP transport in section `" +#~ "%s' under `%s'.\n" #~ msgstr "" #~ "Du måste ange ett namn på röret för SMTP-transporten i sektion \"%s\" " #~ "under \"%s\".\n" diff --git a/po/vi.po b/po/vi.po index 7efd3a1f3..07800a47c 100644 --- a/po/vi.po +++ b/po/vi.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gnunet 0.8.0a\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2022-11-04 14:22+0900\n" +"POT-Creation-Date: 2022-11-14 08:54+0100\n" "PO-Revision-Date: 2008-09-10 22:05+0930\n" "Last-Translator: Clytie Siddall \n" "Language-Team: Vietnamese \n" @@ -4703,23 +4703,23 @@ msgstr "hiển thị giá trị tổng kiểm của tập tin" msgid "Maintain egos" msgstr "" -#: src/identity/gnunet-service-identity.c:685 -#: src/identity/gnunet-service-identity.c:804 +#: src/identity/gnunet-service-identity.c:687 +#: src/identity/gnunet-service-identity.c:806 #, fuzzy, c-format msgid "Failed to write subsystem default identifier map to `%s'.\n" msgstr "Lỗi đọc danh sách bạn bè từ « %s »\n" -#: src/identity/gnunet-service-identity.c:919 +#: src/identity/gnunet-service-identity.c:921 #, fuzzy, c-format msgid "Failed to parse ego information in `%s'\n" msgstr "Lỗi đọc danh sách bạn bè từ « %s »\n" -#: src/identity/gnunet-service-identity.c:977 +#: src/identity/gnunet-service-identity.c:979 #, fuzzy, c-format msgid "Failed to parse subsystem identity configuration file `%s'\n" msgstr "Không thể lưu tập tin cấu hình « %s »:" -#: src/identity/gnunet-service-identity.c:986 +#: src/identity/gnunet-service-identity.c:988 #, fuzzy, c-format msgid "Failed to create directory `%s' for storing egos\n" msgstr "Lỗi đọc danh sách bạn bè từ « %s »\n" @@ -10829,8 +10829,8 @@ msgstr "Không kết nối được đến trình nền gnunetd." #, fuzzy #~ msgid "" -#~ "Syntax error in topology specification at offset %llu, skipping bytes " -#~ "`%s'.\n" +#~ "Syntax error in topology specification at offset %llu, skipping bytes `" +#~ "%s'.\n" #~ msgstr "" #~ "Lỗi cú pháp trong sự xác định địa hình học, đang bỏ qua các byte « %s ».\n" diff --git a/po/zh_CN.po b/po/zh_CN.po index 50e8fc217..576e6b0b7 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gnunet-0.8.1\n" "Report-Msgid-Bugs-To: gnunet-developers@mail.gnu.org\n" -"POT-Creation-Date: 2022-11-04 14:22+0900\n" +"POT-Creation-Date: 2022-11-14 08:54+0100\n" "PO-Revision-Date: 2011-07-09 12:12+0800\n" "Last-Translator: Wylmer Wang \n" "Language-Team: Chinese (simplified) \n" @@ -4520,23 +4520,23 @@ msgstr "显示一个文件的散列值" msgid "Maintain egos" msgstr "" -#: src/identity/gnunet-service-identity.c:685 -#: src/identity/gnunet-service-identity.c:804 +#: src/identity/gnunet-service-identity.c:687 +#: src/identity/gnunet-service-identity.c:806 #, fuzzy, c-format msgid "Failed to write subsystem default identifier map to `%s'.\n" msgstr "解析配置文件“%s”失败\n" -#: src/identity/gnunet-service-identity.c:919 +#: src/identity/gnunet-service-identity.c:921 #, fuzzy, c-format msgid "Failed to parse ego information in `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/identity/gnunet-service-identity.c:977 +#: src/identity/gnunet-service-identity.c:979 #, fuzzy, c-format msgid "Failed to parse subsystem identity configuration file `%s'\n" msgstr "解析配置文件“%s”失败\n" -#: src/identity/gnunet-service-identity.c:986 +#: src/identity/gnunet-service-identity.c:988 #, fuzzy, c-format msgid "Failed to create directory `%s' for storing egos\n" msgstr "解析配置文件“%s”失败\n" diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index 3d8ec2bac..56df4bfc7 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am @@ -273,7 +273,7 @@ endif if ENABLE_TEST_RUN -AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; $(MONKEY) +AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; TESTS = \ test_fs_directory \ test_fs_download \ diff --git a/src/include/gnunet_pq_lib.h b/src/include/gnunet_pq_lib.h index d52c0e40d..4ea286b9f 100644 --- a/src/include/gnunet_pq_lib.h +++ b/src/include/gnunet_pq_lib.h @@ -146,6 +146,39 @@ struct GNUNET_PQ_QueryParam GNUNET_PQ_query_param_bool (bool b); +/** + * Information for an array argument. + */ +struct GNUNET_PQ_ArraySpec +{ + /** + * Number of dimensions of the array + */ + unsigned int ndims; + + /** + * Array of @e ndims lengths of the array + */ + unsigned int *lens; + + /** + * One-dimensional array of pointers to conversion functions for the + * elements in the array. + */ + const struct GNUNET_PQ_QueryParam *ae; + +}; + + +/** + * Generate query parameter for an array. + * + * @param as array specification + */ +struct GNUNET_PQ_QueryParam +GNUNET_PQ_query_param_array (const struct GNUNET_PQ_ArraySpec *as); + + /** * Generate fixed-size query parameter with size determined * by variable type. diff --git a/src/pq/Makefile.am b/src/pq/Makefile.am index 013b20588..d4afe9232 100644 --- a/src/pq/Makefile.am +++ b/src/pq/Makefile.am @@ -5,6 +5,14 @@ if USE_COVERAGE AM_CFLAGS = --coverage endif +sqldir = $(prefix)/share/gnunet/sql/ + +sql_DATA = \ + versioning.sql + +EXTRA_DIST = \ + $(sql_DATA) + if HAVE_POSTGRESQL lib_LTLIBRARIES = libgnunetpq.la endif @@ -27,6 +35,7 @@ libgnunetpq_la_LDFLAGS = \ -version-info 3:0:0 if ENABLE_TEST_RUN +AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; TESTS = \ test_pq endif diff --git a/src/pq/pq_connect.c b/src/pq/pq_connect.c index a911bf8e1..e8617a5c9 100644 --- a/src/pq/pq_connect.c +++ b/src/pq/pq_connect.c @@ -352,6 +352,7 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) PQsetNoticeProcessor (db->conn, &pq_notice_processor_cb, db); + if (NULL != db->load_path) { PGresult *res; ExecStatusType est; @@ -414,6 +415,7 @@ GNUNET_PQ_reconnect (struct GNUNET_PQ_Context *db) { PGresult *res; + GNUNET_assert (NULL != db->load_path); res = PQprepare (db->conn, "gnunet_pq_check_patch", "SELECT" diff --git a/src/pq/pq_eval.c b/src/pq/pq_eval.c index 5f96ff884..cc16c7864 100644 --- a/src/pq/pq_eval.c +++ b/src/pq/pq_eval.c @@ -255,11 +255,11 @@ GNUNET_PQ_eval_prepared_multi_select (struct GNUNET_PQ_Context *db, * codes to `enum GNUNET_DB_QueryStatus`. */ enum GNUNET_DB_QueryStatus -GNUNET_PQ_eval_prepared_singleton_select (struct GNUNET_PQ_Context *db, - const char *statement_name, - const struct - GNUNET_PQ_QueryParam *params, - struct GNUNET_PQ_ResultSpec *rs) +GNUNET_PQ_eval_prepared_singleton_select ( + struct GNUNET_PQ_Context *db, + const char *statement_name, + const struct GNUNET_PQ_QueryParam *params, + struct GNUNET_PQ_ResultSpec *rs) { PGresult *result; enum GNUNET_DB_QueryStatus qs; diff --git a/src/pq/versioning.sql b/src/pq/versioning.sql new file mode 100644 index 000000000..116f409b7 --- /dev/null +++ b/src/pq/versioning.sql @@ -0,0 +1,293 @@ +-- LICENSE AND COPYRIGHT +-- +-- Copyright (C) 2010 Hubert depesz Lubaczewski +-- +-- This program is distributed under the (Revised) BSD License: +-- L +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- +-- * Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- * Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- * Neither the name of Hubert depesz Lubaczewski's Organization +-- nor the names of its contributors may be used to endorse or +-- promote products derived from this software without specific +-- prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- +-- Code origin: https://gitlab.com/depesz/Versioning/blob/master/install.versioning.sql +-- +-- +-- # NAME +-- +-- **Versioning** - simplistic take on tracking and applying changes to databases. +-- +-- # DESCRIPTION +-- +-- This project strives to provide simple way to manage changes to +-- database. +-- +-- Instead of making changes on development server, then finding +-- differences between production and development, deciding which ones +-- should be installed on production, and finding a way to install them - +-- you start with writing diffs themselves! +-- +-- # INSTALLATION +-- +-- To install versioning simply run install.versioning.sql in your database +-- (all of them: production, stage, test, devel, ...). +-- +-- # USAGE +-- +-- In your files with patches to database, put whole logic in single +-- transaction, and use \_v.\* functions - usually \_v.register_patch() at +-- least to make sure everything is OK. +-- +-- For example. Let's assume you have patch files: +-- +-- ## 0001.sql: +-- +-- ``` +-- create table users (id serial primary key, username text); +-- ``` +-- +-- ## 0002.sql: +-- +-- ``` +-- insert into users (username) values ('depesz'); +-- ``` +-- To change it to use versioning you would change the files, to this +-- state: +-- +-- 0000.sql: +-- +-- ``` +-- BEGIN; +-- select _v.register_patch('000-base', NULL, NULL); +-- create table users (id serial primary key, username text); +-- COMMIT; +-- ``` +-- +-- ## 0002.sql: +-- +-- ``` +-- BEGIN; +-- select _v.register_patch('001-users', ARRAY['000-base'], NULL); +-- insert into users (username) values ('depesz'); +-- COMMIT; +-- ``` +-- +-- This will make sure that patch 001-users can only be applied after +-- 000-base. +-- +-- # AVAILABLE FUNCTIONS +-- +-- ## \_v.register_patch( TEXT ) +-- +-- Registers named patch, or dies if it is already registered. +-- +-- Returns integer which is id of patch in \_v.patches table - only if it +-- succeeded. +-- +-- ## \_v.register_patch( TEXT, TEXT[] ) +-- +-- Same as \_v.register_patch( TEXT ), but checks is all given patches (given as +-- array in second argument) are already registered. +-- +-- ## \_v.register_patch( TEXT, TEXT[], TEXT[] ) +-- +-- Same as \_v.register_patch( TEXT, TEXT[] ), but also checks if there are no conflicts with preexisting patches. +-- +-- Third argument is array of names of patches that conflict with current one. So +-- if any of them is installed - register_patch will error out. +-- +-- ## \_v.unregister_patch( TEXT ) +-- +-- Removes information about given patch from the versioning data. +-- +-- It doesn't remove objects that were created by this patch - just removes +-- metainformation. +-- +-- ## \_v.assert_user_is_superuser() +-- +-- Make sure that current patch is being loaded by superuser. +-- +-- If it's not - it will raise exception, and break transaction. +-- +-- ## \_v.assert_user_is_not_superuser() +-- +-- Make sure that current patch is not being loaded by superuser. +-- +-- If it is - it will raise exception, and break transaction. +-- +-- ## \_v.assert_user_is_one_of(TEXT, TEXT, ... ) +-- +-- Make sure that current patch is being loaded by one of listed users. +-- +-- If ```current_user``` is not listed as one of arguments - function will raise +-- exception and break the transaction. + +BEGIN; + +-- This file adds versioning support to database it will be loaded to. +-- It requires that PL/pgSQL is already loaded - will raise exception otherwise. +-- All versioning "stuff" (tables, functions) is in "_v" schema. + +-- All functions are defined as 'RETURNS SETOF INT4' to be able to make them to RETURN literally nothing (0 rows). +-- >> RETURNS VOID<< IS similar, but it still outputs "empty line" in psql when calling. +CREATE SCHEMA IF NOT EXISTS _v; +COMMENT ON SCHEMA _v IS 'Schema for versioning data and functionality.'; + +CREATE TABLE IF NOT EXISTS _v.patches ( + patch_name TEXT PRIMARY KEY, + applied_tsz TIMESTAMPTZ NOT NULL DEFAULT now(), + applied_by TEXT NOT NULL, + requires TEXT[], + conflicts TEXT[] +); +COMMENT ON TABLE _v.patches IS 'Contains information about what patches are currently applied on database.'; +COMMENT ON COLUMN _v.patches.patch_name IS 'Name of patch, has to be unique for every patch.'; +COMMENT ON COLUMN _v.patches.applied_tsz IS 'When the patch was applied.'; +COMMENT ON COLUMN _v.patches.applied_by IS 'Who applied this patch (PostgreSQL username)'; +COMMENT ON COLUMN _v.patches.requires IS 'List of patches that are required for given patch.'; +COMMENT ON COLUMN _v.patches.conflicts IS 'List of patches that conflict with given patch.'; + +CREATE OR REPLACE FUNCTION _v.register_patch( IN in_patch_name TEXT, IN in_requirements TEXT[], in_conflicts TEXT[], OUT versioning INT4 ) RETURNS setof INT4 AS $$ +DECLARE + t_text TEXT; + t_text_a TEXT[]; + i INT4; +BEGIN + -- Thanks to this we know only one patch will be applied at a time + LOCK TABLE _v.patches IN EXCLUSIVE MODE; + + SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_patch_name; + IF FOUND THEN + RAISE EXCEPTION 'Patch % is already applied!', in_patch_name; + END IF; + + t_text_a := ARRAY( SELECT patch_name FROM _v.patches WHERE patch_name = any( in_conflicts ) ); + IF array_upper( t_text_a, 1 ) IS NOT NULL THEN + RAISE EXCEPTION 'Versioning patches conflict. Conflicting patche(s) installed: %.', array_to_string( t_text_a, ', ' ); + END IF; + + IF array_upper( in_requirements, 1 ) IS NOT NULL THEN + t_text_a := '{}'; + FOR i IN array_lower( in_requirements, 1 ) .. array_upper( in_requirements, 1 ) LOOP + SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_requirements[i]; + IF NOT FOUND THEN + t_text_a := t_text_a || in_requirements[i]; + END IF; + END LOOP; + IF array_upper( t_text_a, 1 ) IS NOT NULL THEN + RAISE EXCEPTION 'Missing prerequisite(s): %.', array_to_string( t_text_a, ', ' ); + END IF; + END IF; + + INSERT INTO _v.patches (patch_name, applied_tsz, applied_by, requires, conflicts ) VALUES ( in_patch_name, now(), current_user, coalesce( in_requirements, '{}' ), coalesce( in_conflicts, '{}' ) ); + RETURN; +END; +$$ language plpgsql; +COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[], TEXT[] ) IS 'Function to register patches in database. Raises exception if there are conflicts, prerequisites are not installed or the migration has already been installed.'; + +CREATE OR REPLACE FUNCTION _v.register_patch( TEXT, TEXT[] ) RETURNS setof INT4 AS $$ + SELECT _v.register_patch( $1, $2, NULL ); +$$ language sql; +COMMENT ON FUNCTION _v.register_patch( TEXT, TEXT[] ) IS 'Wrapper to allow registration of patches without conflicts.'; +CREATE OR REPLACE FUNCTION _v.register_patch( TEXT ) RETURNS setof INT4 AS $$ + SELECT _v.register_patch( $1, NULL, NULL ); +$$ language sql; +COMMENT ON FUNCTION _v.register_patch( TEXT ) IS 'Wrapper to allow registration of patches without requirements and conflicts.'; + +CREATE OR REPLACE FUNCTION _v.unregister_patch( IN in_patch_name TEXT, OUT versioning INT4 ) RETURNS setof INT4 AS $$ +DECLARE + i INT4; + t_text_a TEXT[]; +BEGIN + -- Thanks to this we know only one patch will be applied at a time + LOCK TABLE _v.patches IN EXCLUSIVE MODE; + + t_text_a := ARRAY( SELECT patch_name FROM _v.patches WHERE in_patch_name = ANY( requires ) ); + IF array_upper( t_text_a, 1 ) IS NOT NULL THEN + RAISE EXCEPTION 'Cannot uninstall %, as it is required by: %.', in_patch_name, array_to_string( t_text_a, ', ' ); + END IF; + + DELETE FROM _v.patches WHERE patch_name = in_patch_name; + GET DIAGNOSTICS i = ROW_COUNT; + IF i < 1 THEN + RAISE EXCEPTION 'Patch % is not installed, so it can''t be uninstalled!', in_patch_name; + END IF; + + RETURN; +END; +$$ language plpgsql; +COMMENT ON FUNCTION _v.unregister_patch( TEXT ) IS 'Function to unregister patches in database. Dies if the patch is not registered, or if unregistering it would break dependencies.'; + +CREATE OR REPLACE FUNCTION _v.assert_patch_is_applied( IN in_patch_name TEXT ) RETURNS TEXT as $$ +DECLARE + t_text TEXT; +BEGIN + SELECT patch_name INTO t_text FROM _v.patches WHERE patch_name = in_patch_name; + IF NOT FOUND THEN + RAISE EXCEPTION 'Patch % is not applied!', in_patch_name; + END IF; + RETURN format('Patch %s is applied.', in_patch_name); +END; +$$ language plpgsql; +COMMENT ON FUNCTION _v.assert_patch_is_applied( TEXT ) IS 'Function that can be used to make sure that patch has been applied.'; + +CREATE OR REPLACE FUNCTION _v.assert_user_is_superuser() RETURNS TEXT as $$ +DECLARE + v_super bool; +BEGIN + SELECT usesuper INTO v_super FROM pg_user WHERE usename = current_user; + IF v_super THEN + RETURN 'assert_user_is_superuser: OK'; + END IF; + RAISE EXCEPTION 'Current user is not superuser - cannot continue.'; +END; +$$ language plpgsql; +COMMENT ON FUNCTION _v.assert_user_is_superuser() IS 'Function that can be used to make sure that patch is being applied using superuser account.'; + +CREATE OR REPLACE FUNCTION _v.assert_user_is_not_superuser() RETURNS TEXT as $$ +DECLARE + v_super bool; +BEGIN + SELECT usesuper INTO v_super FROM pg_user WHERE usename = current_user; + IF v_super THEN + RAISE EXCEPTION 'Current user is superuser - cannot continue.'; + END IF; + RETURN 'assert_user_is_not_superuser: OK'; +END; +$$ language plpgsql; +COMMENT ON FUNCTION _v.assert_user_is_not_superuser() IS 'Function that can be used to make sure that patch is being applied using normal (not superuser) account.'; + +CREATE OR REPLACE FUNCTION _v.assert_user_is_one_of(VARIADIC p_acceptable_users TEXT[] ) RETURNS TEXT as $$ +DECLARE +BEGIN + IF current_user = any( p_acceptable_users ) THEN + RETURN 'assert_user_is_one_of: OK'; + END IF; + RAISE EXCEPTION 'User is not one of: % - cannot continue.', p_acceptable_users; +END; +$$ language plpgsql; +COMMENT ON FUNCTION _v.assert_user_is_one_of(TEXT[]) IS 'Function that can be used to make sure that patch is being applied by one of defined users.'; + +COMMIT; diff --git a/src/util/crypto_crc.c b/src/util/crypto_crc.c index a2ffdb543..8b0449d4b 100644 --- a/src/util/crypto_crc.c +++ b/src/util/crypto_crc.c @@ -56,18 +56,17 @@ static void crc_init () { static int once; - unsigned int i, j; GNUNET_uLong h = 1; if (once) return; once = 1; crc_table[0] = 0; - for (i = 128; i; i >>= 1) + for (unsigned int i = 128; i; i >>= 1) { h = (h >> 1) ^ ((h & 1) ? POLYNOMIAL : 0); /* h is now crc_table[i] */ - for (j = 0; j < 256; j += 2 * i) + for (unsigned int j = 0; j < 256; j += 2 * i) crc_table[i + j] = crc_table[j] ^ h; } } -- cgit v1.2.3