]> uap-core.de Git - note.git/commitdiff
add first db tables and usersettings initialization
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 16 Feb 2025 11:46:39 +0000 (12:46 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 16 Feb 2025 11:46:39 +0000 (12:46 +0100)
16 files changed:
application/Makefile
application/application.c
application/application.h
application/main.c
application/store.c
application/store.h
application/store_sqlite.c [new file with mode: 0644]
application/store_sqlite.h [new file with mode: 0644]
application/types.c [new file with mode: 0644]
application/types.h [new file with mode: 0644]
application/window.c
dbutils/db.c
dbutils/dbutils.c
dbutils/dbutils/db.h
dbutils/dbutils/dbutils.h
dbutils/object.c

index 65c372a6e8e2aa8315c0acbd1d17d96edd5c543f..24b3e939b68ed85b42629eb8959bf1c472e0731a 100644 (file)
@@ -34,7 +34,9 @@ CFLAGS += -I../ui/ -I../ucx -I..
 SRC  = main.c
 SRC += application.c
 SRC += window.c
+SRC += types.c
 SRC += store.c
+SRC += store_sqlite.c
 
 OBJ = $(SRC:%.c=../build/application/%.$(OBJ_EXT))
        
index bd6dd4f2c2485266994d3aac7b40aa52f57925bc..42c7794beea092637d25c643d97fa0da6ec7f033 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2024 Olaf Wintermann. All rights reserved.
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
 #include "window.h"
 #include "store.h"
 
+#include <unistd.h>
+#include <limits.h>
+
+#include <cx/mempool.h>
+
 void application_startup(UiEvent *event, void *data) {
-    if(init_note_store) {
+    if(init_note_store()) {
+        fprintf(stderr, "note store initialization failed\n");
         return;
     }
     
+    // Get environment required by settings
+    char hostname[HOST_NAME_MAX];
+    char *host = NULL;
+    if(gethostname(hostname, sizeof(hostname)) == 0) {
+        host = hostname;
+    }
+    char *user = getenv("USER");
+    
+    // Get available user settings
+    // The first entry should be the default, however it must be checked if
+    // it is valid for this environment
+    CxMempool *mp = cxMempoolCreate(64, NULL);
+    CxList *usersettings = note_store_get_user_settings(mp->allocator, host, user, NULL);
+    int settings_valid = 0;
+    if(usersettings && cxListSize(usersettings) > 0) {
+        UserSettings *settings = cxListAt(usersettings, 0);
+        if(user_settings_is_valid(settings, host, user, NULL)) {
+            note_store_set_settings(
+                    settings->host,
+                    settings->user,
+                    settings->profile_name,
+                    settings->default_repository_id,
+                    settings->default_collection_id);
+            settings_valid = 1;
+        }
+    }
+    
+    if(!settings_valid) {
+        // no valid settings (or no settings)
+        // TODO: Show a initialization dialog, where the user could
+        //       select available settings or create new settings
+        fprintf(stderr, "TODO: settings prompt\n");
+        exit(-1);
+    }
+    
+    cxMempoolFree(mp);
+    
     window_create();
 }
index 7046b8fac2dac388719ae8e90fd82aa254bc7d9c..acae80e12a1f1603589bfa46d7125a93d7cdaa72 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2024 Olaf Wintermann. All rights reserved.
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
index 5fb3c4c6121949d11393065bb0cdda7a510b0f2a..b2b5f77fd5b4a91f84b1b5c5e60b00e7d74cae04 100644 (file)
 #include <ui/ui.h>\r
 \r
 #include "application.h"\r
+#include "types.h"\r
 \r
 int app_main(int argc, char **argv) {\r
+    register_types();\r
     ui_init("note", argc, argv);\r
     ui_onstartup(application_startup, NULL);\r
     ui_main();\r
index 16825416e814a5457a69347ca3f0ed66bd3c9511..56d41dfcf1191a67486d68f998813c4d1f132de2 100644 (file)
 #include <errno.h>
 #include <sys/stat.h>
 
+#include "types.h"
+#include "store_sqlite.h"
+
 #include "../dbutils/dbutils/db.h"
 #include "../dbutils/dbutils/sqlite.h"
 
 static DBUConnection *connection;
 
+static char *settings_host;
+static char *settings_user;
+static char *settings_profile_name;
+static int64_t settings_default_repository_id;
+static int64_t settings_default_node_id;
+
+/*
+ * Creates a connection to the note database and initializes tables if necessary
+ * 
+ * Returns:
+ *   0 on success
+ *   1 on error
+ */
 int init_note_store() {
     char *sqlite_db_file = ui_configfile(NOTES_DB_FILE);
     
@@ -59,5 +75,93 @@ int init_note_store() {
         return 1;
     }
     
+    if(init_db) {
+        if(store_sqlite_init_db(connection)) {
+            return 1;
+        }
+    }
+    
     return 0;
 }
+
+/*
+ * Gets a list of all available user settings, sorted by relevance. Usually
+ * the first item should be used as default settings, however the
+ * host/user/profile fields should be checked.
+ */
+CxList* note_store_get_user_settings(const CxAllocator *a, const char *host, const char *user, const char *profile) {
+    DBUQuery *query = connection->createQuery(connection, NULL);
+    dbuQuerySetSQL(query, "select * from user_settings;");
+    if(host) {
+        dbuQuerySetParamString(query, 0, cx_str(host));
+    } else {
+        dbuQuerySetParamNull(query, 0);
+    }
+    if(user) {
+        dbuQuerySetParamString(query, 1, cx_str(user));
+    } else {
+        dbuQuerySetParamNull(query, 1);
+    }
+    if(profile) {
+        dbuQuerySetParamString(query, 2, cx_str(profile));
+    } else {
+        dbuQuerySetParamNull(query, 2);
+    }
+    
+    DBUObjectBuilder *builder = dbuObjectBuilder(usersettings_class, query, a);
+    CxList *usersettings = dbuObjectBuilderGetList(builder);
+    dbuObjectBuilderDestroy(builder);
+    
+    return usersettings;
+}
+
+void close_note_store() {
+    connection->free(connection);
+}
+
+
+/*
+ * Checks if the settings object complies to the specified host/user/profile.
+ * 
+ * A settings field (like host) must be NULL or have the same specified value.
+ * 
+ * Returns:
+ *   1: settings are valid
+ *   0: settings are not valid
+ */
+int user_settings_is_valid(
+        UserSettings *settings,
+        const char *host,
+        const char *user,
+        const char *profile)
+{
+    if(!settings) return 0;
+    if(settings->host && host && strcmp(settings->host, host)) {
+        return 0;
+    }
+    if(settings->user && host && strcmp(settings->user, user)) {
+        return 0;
+    }
+    if(settings->profile_name && profile && strcmp(settings->profile_name, profile)) {
+        return 0;
+    }
+    return 1;
+}
+
+/*
+ * Sets global settings
+ */
+void note_store_set_settings(
+        const char *host,
+        const char *user,
+        const char *profile_name,
+        int64_t default_repository_id,
+        int64_t default_node_id)
+{
+    settings_host = host ? strdup(host) : NULL;
+    settings_user = user ? strdup(user) : NULL;
+    settings_profile_name = profile_name ? strdup(profile_name) : NULL;
+    settings_default_repository_id = default_repository_id;
+    settings_default_node_id = default_node_id;
+}
+
index 2459c213e3cbdfb3360e8294ea87a0e97613c455..d603faab21c72c166da8b461cf50c470c7f4e1ca 100644 (file)
 #define STORE_H
 
 #include "application.h"
+#include "types.h"
+#include <cx/list.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 #define NOTES_DB_FILE "notes.db"
-    
+      
 int init_note_store();
 
+CxList* note_store_get_user_settings(const CxAllocator *a, const char *host, const char *user, const char *profile);
+
+void close_note_store();
+
+int user_settings_is_valid(
+        UserSettings *settings,
+        const char *host,
+        const char *user,
+        const char *profile);
+
+void note_store_set_settings(
+        const char *host,
+        const char *user,
+        const char *profile_name,
+        int64_t default_repository_id,
+        int64_t default_node_id);
+
 
 #ifdef __cplusplus
 }
diff --git a/application/store_sqlite.c b/application/store_sqlite.c
new file mode 100644 (file)
index 0000000..728c921
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. 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.
+ *
+ * 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 HOLDER 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.
+ */
+
+#include "store_sqlite.h"
+
+#include <stdio.h>
+#include "../dbutils/dbutils/sqlite.h"
+
+
+#define SQL_CREATE_TABLE_NOTEDB "create table note_db( " \
+    "version int, " \
+    "created text);"
+#define SQL_CREATE_TABLE_REPOSITORIES "create table repositories( " \
+    "repository_id integer primary key, " \
+    "name          text not null unique, " \
+    "url           text, " \
+    "encryption    integer, " \
+    "default_key   text, " \
+    "authmethod    integer, " \
+    "local_path    text);" 
+#define SQL_CREATE_TABLE_COLLECTIONS "create table collections( " \
+    "collection_id           integer primary key, " \
+    "parent_id               integer, " \
+    "repository_id           integer, " \
+    "name                    text not null, " \
+    "display_name            text, " \
+    "type                    text, " \
+    "created_by              text, " \
+    "created_at              text, " \
+    "foreign key (parent_id) references collections(collection_id), " \
+    "foreign key (repository_id) references repositories(repository_id)" \
+    ");"
+#define SQL_CREATE_TABLE_USER_SETTINGS "create table user_settings( " \
+    "host                    text, " \
+    "user                    text, " \
+    "profile_name            text, " \
+    "default_repository_id   integer, " \
+    "default_collection_id   integer, " \
+    "created_by              text, " \
+    "created_at              text, " \
+    "foreign key (default_repository_id) references repositories(repository_id), " \
+    "foreign key (default_collection_id) references collections(collection_id), " \
+    "unique (host, user, profile_name)" \
+    ");"
+
+int store_sqlite_init_db(DBUConnection *connection) {
+    char *sql[] = { 
+        SQL_CREATE_TABLE_NOTEDB,
+        SQL_CREATE_TABLE_REPOSITORIES,
+        SQL_CREATE_TABLE_COLLECTIONS,
+        SQL_CREATE_TABLE_USER_SETTINGS
+    };
+    int nsql = sizeof(sql) / sizeof(char*);
+    
+    for(int i=0;i<nsql;i++) {
+        if(dbuConnectionExec(connection, sql[i])) {
+            fprintf(stderr, "sqlite error: query failed\n%s\n", sql[i]);
+            return 1;
+        }
+    }
+    
+    return 0;
+}
diff --git a/application/store_sqlite.h b/application/store_sqlite.h
new file mode 100644 (file)
index 0000000..7a30fc7
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. 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.
+ *
+ * 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 HOLDER 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.
+ */
+
+#ifndef STORE_SQLITE_H
+#define STORE_SQLITE_H
+
+#include "../dbutils/dbutils/db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int store_sqlite_init_db(DBUConnection *connection);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STORE_SQLITE_H */
+
diff --git a/application/types.c b/application/types.c
new file mode 100644 (file)
index 0000000..2498b45
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. 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.
+ *
+ * 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 HOLDER 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.
+ */
+
+#include "types.h"
+
+static DBUContext *ctx;
+
+DBUClass *usersettings_class;
+DBUClass *repository_class;
+DBUClass *collection_class;
+
+DBUContext* get_dbu_context() {
+    return ctx;
+}
+
+void register_types() {
+    ctx = dbuContextCreate();
+    
+    usersettings_class = dbuRegisterClassWithoutPK(ctx, "user_settings", sizeof(UserSettings));
+    dbuClassAdd(usersettings_class, UserSettings, host);
+    dbuClassAdd(usersettings_class, UserSettings, user);
+    dbuClassAdd(usersettings_class, UserSettings, profile_name);
+    dbuClassAdd(usersettings_class, UserSettings, default_repository_id);
+    dbuClassAdd(usersettings_class, UserSettings, default_collection_id);
+    dbuClassAdd(usersettings_class, UserSettings, created_by);
+    
+}
\ No newline at end of file
diff --git a/application/types.h b/application/types.h
new file mode 100644 (file)
index 0000000..c82629c
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. 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.
+ *
+ * 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 HOLDER 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.
+ */
+
+#ifndef APP_TYPES_H
+#define APP_TYPES_H
+
+#include "../dbutils/dbutils/dbutils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct UserSettings UserSettings;
+typedef struct Repository   Repository;
+typedef struct Collection   Collection;
+    
+struct UserSettings {
+    char    *host;
+    char    *user;
+    char    *profile_name;
+    int64_t default_repository_id;
+    int64_t default_collection_id;
+    char    *created_by;
+    // created_at
+};
+
+struct Repository {
+    int64_t    repository_id;
+    char       *name;
+    char       *url;
+    char       *local_path;
+    char       *default_key;
+    int        authmethod;
+    bool       encryption;
+};
+
+struct Collection {
+    int64_t    collection_id;
+    int64_t    parent_id;
+    int64_t    repository_id;
+    char       *name;
+    char       *display_name;
+    char       *type;
+};
+
+extern DBUClass *usersettings_class;
+extern DBUClass *repository_class;
+extern DBUClass *collection_class;
+
+void register_types();
+
+DBUContext* get_dbu_context();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_TYPES_H */
+
index b904b8bf32a4fe2f595540ed3daaebd15289a654..d731c60f0478663a5c9648c3609033bbfd65d585 100644 (file)
@@ -53,7 +53,7 @@ void window_create() {
         
         // splitpane right: content
         ui_grid(obj, .columnspacing = 10, .rowspacing = 10) {
-            ui_label(obj, .label = "Title");
+            ui_label(obj, .label = "Title", .vfill = TRUE);
             ui_textfield(obj, .varname = "note_title", .hexpand = TRUE, .groups = UI_GROUPS(APP_STATE_NOTE_SELECTED));
             ui_newline(obj);
             
index 9ffa8f429706d47aefbded2df26195202689a16c..d7f2500c4aa321404d9641b2604680b3caba20ca 100644 (file)
 #include "db.h"
 #include "dbutils/db.h"
 
+int dbuConnectionExec(DBUConnection *conn, const char *sql) {
+    DBUQuery *q = conn->createQuery(conn, NULL);
+    int err = 1;
+    if(!dbuQuerySetSQL(q, sql)) {
+        err = dbuQueryExec(q);
+    } 
+    dbuQueryFree(q);
+    return err;
+}
+
+
+
 int dbuQuerySetSQL(DBUQuery *q, const char *sql) {
     return q->setSQL(q, sql);
 }
index ab93ac9b92939e7990f2fb796eb6f8ca904f0949..68b013e158a1eeb01fc3da34b11a15b40de2212f 100644 (file)
@@ -134,3 +134,15 @@ DBUClass* dbuRegisterClassWithPrimaryKeyCxMutStr(
     cxMapPut(context->classes, name, cls);
     return cls;
 }
+
+DBUClass* dbuRegisterClassWithoutPK(
+        DBUContext *context,
+        const char *name,
+        size_t obj_size)
+{
+    DBUClass *cls = dbuClassCreate(name);
+    cls->context = context;
+    cls->obj_size = obj_size;
+    cxMapPut(context->classes, name, cls);
+    return cls;
+}
index d8710866f19e9e933d284b9dd5150e310246fbe3..167204b85dcba9ed9ef2a888c5e32c646adab33a 100644 (file)
@@ -96,6 +96,7 @@ struct DBUResult {
     int rowIndex;
 };
 
+int dbuConnectionExec(DBUConnection *conn, const char *sql);
 
 int dbuQuerySetSQL(DBUQuery *q, const char *sql);
 int dbuQuerySetParamString(DBUQuery *q, int index, cxstring str);
index cc24281403a6065b4222c1b429958a43cde8cbc1..e11ac4c1edf8300cdc4e9c8e7e7f47929ee310eb 100644 (file)
@@ -265,6 +265,10 @@ DBUClass* dbuRegisterClassWithPrimaryKeyCxMutStr(
         size_t obj_size,
         const char *primary_key_column,
         off_t primary_key_offset);
+DBUClass* dbuRegisterClassWithoutPK(
+        DBUContext *context,
+        const char *name,
+        size_t obj_size);
 
 void dbuClassSetPrimaryKeyInt32(DBUClass *cls, const char *column_name, off_t offset);
 void dbuClassSetPrimaryKeyUInt32(DBUClass *cls, const char *column_name, off_t offset);
index deff5cd52f046a863a5fc106511dd4e7d4a3b01e..0a54c30737d9cbe1ed4126c31a3d1e6ad024ab2a 100644 (file)
@@ -449,7 +449,9 @@ int dbuObjectExecuteQuery(DBUObjectBuilder *builder, DBUQuery *query, DBUClass *
             DBUField *type_field = field.field;
             if(type_field && current_obj) {
                 if(isnull) {
-                    field.field->initDefaultValue(field.field, a, current_obj);
+                    if(field.field->initDefaultValue) {
+                        field.field->initDefaultValue(field.field, a, current_obj);
+                    }
                 } else {
                     cxstring text = result->getText(result, i);
                     //printf("getText(%d) = %s\n", i, text.ptr);