]> Nishi Git Mirror - dataworks.git/commitdiff
check lock
authornishi <nishi@d4a5a174-5a4a-5b4b-b672-37683c10d7d5>
Mon, 27 May 2024 03:42:24 +0000 (03:42 +0000)
committernishi <nishi@d4a5a174-5a4a-5b4b-b672-37683c10d7d5>
Mon, 27 May 2024 03:42:24 +0000 (03:42 +0000)
git-svn-id: file:///raid/svn-main/nishi-dataworks/trunk@123 d4a5a174-5a4a-5b4b-b672-37683c10d7d5

FORMATv1.md
Library/database.c
Library/database_record.c
Library/database_table.c
Library/dw_database.h
Library/dw_util.h
Library/util.c

index 485b91a40e45c318a8c7317d69ea7adbd21280f2..f1f97dca79d8d3a981d0aa0a72d0a9e729d2d7ec 100644 (file)
@@ -17,7 +17,7 @@ Database entry (`dbentry`) MUST be in this format:
 | Name | Size | Type | Info |
 | ---- | ---- | ---- | ---- |
 | flag | 1 byte | uint8\_t | |
-| length | 8 bytes | uint64\_t | Size of the entry |
+| length | 8 bytes | uint64\_t | Size of the actual data inside |
 | size | 8 bytes | uint64\_t | |
 | field\_index | 1 byte | uint8\_t | |
 | db\_index | 1 byte | uint8\_t | |
index 31e39801c2df8d4f21abd60ef6cbe3d5babcf291..5f77c7e52391bc161808448c0911f5204e3495b7 100644 (file)
@@ -93,38 +93,39 @@ struct dataworks_db* dataworks_database_open(const char* fname) {
        db->error = false;
        db->fp = NULL;
        db->name = NULL;
-       FILE* fp = fopen(fname, "rb+");
-       if(fp == NULL) {
+       db->locked = false;
+       db->fp = fopen(fname, "rb+");
+       if(db->fp == NULL) {
                db->error = true;
                db->errnum = DW_ERR_FAIL_FOPEN;
                return db;
        }
-       fseek(fp, 0, SEEK_SET);
+       fseek(db->fp, 0, SEEK_SET);
        char readsig[sizeof(sig)];
-       fread(readsig, 1, sizeof(sig), fp);
+       fread(readsig, 1, sizeof(sig), db->fp);
        if(memcmp(readsig, sig, sizeof(sig)) != 0) {
                db->error = true;
                db->errnum = DW_ERR_INVALID_SIGNATURE;
                return db;
        }
-       __dw_lockfile(fp);
+       __dw_lockfile(db);
        char ptrver[8];
-       fread(ptrver, 1, 2, fp);
+       fread(ptrver, 1, 2, db->fp);
        uint16_t be_ver = *(uint16_t*)(char*)ptrver;
        uint16_t ver;
        __dw_native_endian(be_ver, uint16_t, ver = __converted);
-       fread(ptrver, 1, 8, fp);
+       fread(ptrver, 1, 8, db->fp);
        uint64_t be_mtime = *(uint64_t*)(char*)ptrver;
        uint64_t mtime;
        __dw_native_endian(be_mtime, uint64_t, mtime = __converted);
-       __dw_unlockfile(fp);
+       __dw_unlockfile(db);
        if(ver == 1) {
-               db->fp = fp;
                db->version = ver;
                db->mtime = mtime;
                return db;
        } else {
-               fclose(fp);
+               fclose(db->fp);
+               db->fp = NULL;
                db->error = true;
                db->errnum = DW_ERR_INVALID_VERSION;
                return db;
@@ -140,11 +141,11 @@ int dataworks_database_get_error_number(struct dataworks_db* db) { return db->er
 const char* dataworks_database_strerror(int n) { return dw_errors[n]; }
 
 void dataworks_database_update_mtime(struct dataworks_db* db) {
-       __dw_lockfile(db->fp);
+       __dw_lockfile(db);
        fseek(db->fp, 3 + 2, SEEK_SET);
        int64_t t = time(NULL);
        __dw_big_endian(t, int64_t, fwrite(__converted_ptr, 1, 8, db->fp));
-       __dw_unlockfile(db->fp);
+       __dw_unlockfile(db);
 }
 
 void dataworks_database_free(struct dataworks_db* db) {
index f6e70e155c98cc96436eee3ebe22500fb2df6cc8..8937a5272e378f2ce7c4496dfe45e72387d910f9 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-void __dw_add_record(struct dataworks_db* db, uint64_t index, void* _data, uint64_t size, bool set) {
+void __dw_add_record(struct dataworks_db* db, uint64_t dbindex, uint64_t index, void* _data, uint64_t size, bool set) {
        uint8_t* data = _data;
-       __dw_lockfile(db->fp);
+       int fragnum = 0;
+       __dw_lockfile(db);
        if(db->version == 1) {
                char* buf = malloc(1 + 8 + 8 + 1 + 1 + 8 + 8);
                fseek(db->fp, 3 + 2 + 8 + (1 + 8 + 1 + 256 + 4096) * 256, SEEK_SET);
@@ -50,19 +51,39 @@ void __dw_add_record(struct dataworks_db* db, uint64_t index, void* _data, uint6
                        if(!(dbentry.flag & DATAWORKS_V1_DBENTRY_USED)) {
                                fseek(db->fp, -(1 + 8 + 8 + 1 + 1 + 8 + 8), SEEK_CUR);
                                buf[0] |= DATAWORKS_V1_DBENTRY_USED;
+                               if(dbentry.size <= size) {
+                                       if(dbentry.size < size) buf[0] |= DATAWORKS_V1_DBENTRY_FRAGMENT;
+                                       __dw_big_endian(dbentry.size, uint64_t, memcpy(buf + 1, __converted_ptr, 8));
+                                       buf[1 + 8 + 8] = index;
+                                       buf[1 + 8 + 8 + 1] = dbindex;
+                                       __dw_big_endian(fragnum, uint64_t, memcpy(buf + 1 + 8 + 8 + 1 + 1 + 8, __converted_ptr, 8));
+                                       fragnum++;
+                                       size -= dbentry.size;
+                               }
                                fwrite(buf, 1, 1 + 8 + 8 + 1 + 1 + 8 + 8, db->fp);
                        }
                        fseek(db->fp, dbentry.size, SEEK_CUR);
                }
                free(buf);
        }
-       __dw_unlockfile(db->fp);
+       __dw_unlockfile(db);
 }
 
 struct dataworks_db_result* dataworks_database_insert_record(struct dataworks_db* db, void** fields, const char* prop) {
        struct dataworks_db_result* r = malloc(sizeof(*r));
        r->error = false;
        int i;
+       char** dbi = dataworks_database_get_table_list(db);
+       uint64_t dbindex;
+       bool set = false;
+       for(i = 0; dbi[i] != NULL; i++) {
+               if(!set && strcmp(dbi[i], db->name) == 0) {
+                       dbindex = i;
+                       set = true;
+               }
+               free(dbi[i]);
+       }
+       free(dbi);
        char* types = dataworks_database_get_table_field_types(db, db->name);
        for(i = 0; prop[i] != 0; i++)
                ;
@@ -84,7 +105,7 @@ struct dataworks_db_result* dataworks_database_insert_record(struct dataworks_db
                } else if(types[i] == DW_RECORD_HELP) {
                        entsize = strlen(fields[i]);
                }
-               __dw_add_record(db, i, fields[i], entsize, prop[i] == 'S');
+               __dw_add_record(db, dbindex, i, fields[i], entsize, prop[i] == 'S');
        }
        return r;
 }
index 40ea3a7f1a63f95e6872709b5eba7217bbcb09e3..390deda9d3c9b37fd279a563ca3ff69518bef30b 100644 (file)
@@ -37,7 +37,7 @@
 int dataworks_database_delete_table(struct dataworks_db* db, const char* name) {
        bool rm = false;
        if(db->version == 1) {
-               __dw_lockfile(db->fp);
+               __dw_lockfile(db);
                fseek(db->fp, 3 + 10, SEEK_SET);
                int i;
                struct dataworks_db_v1_indexentry index;
@@ -59,7 +59,7 @@ int dataworks_database_delete_table(struct dataworks_db* db, const char* name) {
                        }
                }
                free(buf);
-               __dw_unlockfile(db->fp);
+               __dw_unlockfile(db);
        }
        if(rm) return DW_ERR_SUCCESS;
        return DW_ERR_NOT_USED;
@@ -67,7 +67,7 @@ int dataworks_database_delete_table(struct dataworks_db* db, const char* name) {
 
 int dataworks_database_create_table(struct dataworks_db* db, const char* name, char** fields, const char* fieldtypes) {
        if(db->version == 1) {
-               __dw_lockfile(db->fp);
+               __dw_lockfile(db);
                fseek(db->fp, 3 + 10, SEEK_SET);
                int i;
                struct dataworks_db_v1_indexentry index;
@@ -83,7 +83,7 @@ int dataworks_database_create_table(struct dataworks_db* db, const char* name, c
                                if(strcmp(name, dbname) == 0) {
                                        free(dbname);
                                        free(buf);
-                                       __dw_unlockfile(db->fp);
+                                       __dw_unlockfile(db);
                                        return DW_ERR_USED;
                                }
                                cnt++;
@@ -91,7 +91,7 @@ int dataworks_database_create_table(struct dataworks_db* db, const char* name, c
                }
                if(cnt == 256) {
                        free(buf);
-                       __dw_unlockfile(db->fp);
+                       __dw_unlockfile(db);
                        return DW_ERR_TOO_MANY_TABLES;
                }
                fseek(db->fp, 3 + 10, SEEK_SET);
@@ -115,7 +115,7 @@ int dataworks_database_create_table(struct dataworks_db* db, const char* name, c
                        }
                }
                free(buf);
-               __dw_unlockfile(db->fp);
+               __dw_unlockfile(db);
                dataworks_database_update_mtime(db);
        }
        return DW_ERR_SUCCESS;
@@ -123,7 +123,7 @@ int dataworks_database_create_table(struct dataworks_db* db, const char* name, c
 
 char** dataworks_database_get_table_list(struct dataworks_db* db) {
        if(db->version == 1) {
-               __dw_lockfile(db->fp);
+               __dw_lockfile(db);
                fseek(db->fp, 3 + 10, SEEK_SET);
                int i;
                struct dataworks_db_v1_indexentry index;
@@ -151,14 +151,14 @@ char** dataworks_database_get_table_list(struct dataworks_db* db) {
                }
                list[c] = NULL;
                free(buf);
-               __dw_unlockfile(db->fp);
+               __dw_unlockfile(db);
                return list;
        }
 }
 
 char** dataworks_database_get_table_fields(struct dataworks_db* db, const char* table) {
        if(db->version == 1) {
-               __dw_lockfile(db->fp);
+               __dw_lockfile(db);
                fseek(db->fp, 3 + 10, SEEK_SET);
                int i;
                struct dataworks_db_v1_indexentry index;
@@ -197,21 +197,21 @@ char** dataworks_database_get_table_fields(struct dataworks_db* db, const char*
                                        }
                                        free(dbname);
                                        free(buf);
-                                       __dw_unlockfile(db->fp);
+                                       __dw_unlockfile(db);
                                        return list;
                                }
                                free(dbname);
                        }
                }
                free(buf);
-               __dw_unlockfile(db->fp);
+               __dw_unlockfile(db);
        }
        return NULL;
 }
 
 char* dataworks_database_get_table_field_types(struct dataworks_db* db, const char* table) {
        if(db->version == 1) {
-               __dw_lockfile(db->fp);
+               __dw_lockfile(db);
                fseek(db->fp, 3 + 10, SEEK_SET);
                int i;
                struct dataworks_db_v1_indexentry index;
@@ -245,14 +245,14 @@ char* dataworks_database_get_table_field_types(struct dataworks_db* db, const ch
                                        list[count] = 0;
                                        free(dbname);
                                        free(buf);
-                                       __dw_unlockfile(db->fp);
+                                       __dw_unlockfile(db);
                                        return list;
                                }
                                free(dbname);
                        }
                }
                free(buf);
-               __dw_unlockfile(db->fp);
+               __dw_unlockfile(db);
        }
        return NULL;
 }
index 8deab74df28705c04578c2489f9b2220223c15af..ec265e5aad5c4efc4bcf7326bfe4d82aa23f992c 100644 (file)
@@ -258,10 +258,17 @@ struct dataworks_db {
 
        /**
         * @~english
-        * @brief Database being used.
+        * @brief Table which is being used.
         *
         */
        char* name;
+
+       /**
+        * @~english
+        * @brief Locked or not.
+        *
+        */
+       bool locked;
 };
 
 /**
index b40b24c741e8724a57ffdb4a6b73e61f43bdb4d3..dade3b6c6e67fc308288d8616ea0e4ebbc4e4e2c 100644 (file)
@@ -44,12 +44,13 @@ extern "C" {
 #include <stdio.h>
 
 #include "dataworks.h"
+#include "dw_database.h"
 
 char* __dw_strdup(const char* a);
 char* __dw_strcat(const char* a, const char* b);
 bool __dw_strcaseequ(const char* a, const char* b);
-bool __dw_lockfile(FILE* fp);
-bool __dw_unlockfile(FILE* fp);
+bool __dw_lockfile(struct dataworks_db* db);
+bool __dw_unlockfile(struct dataworks_db* db);
 
 #define __dw_xstr(x) #x
 #define __dw_str(x) __dw_xstr(x)
index b9c488e735a589ddc849350a10a38863dec1c3ba..288f2215686092d3bbed73141a63ae28729f7608 100644 (file)
@@ -62,33 +62,41 @@ bool __dw_strcaseequ(const char* a, const char* b) {
        return true;
 }
 
-bool __dw_lockfile(FILE* fp) {
-       off_t off = ftell(fp);
-       fseek(fp, 0, SEEK_SET);
+bool __dw_lockfile(struct dataworks_db* db) {
+       if(db->locked) {
+               return true;
+       }
+       off_t off = ftell(db->fp);
+       fseek(db->fp, 0, SEEK_SET);
 #if defined(DOS)
 
 #elif defined(__MINGW32__)
        OVERLAPPED overlap = {0};
-       LockFileEx(fp, LOCKFILE_EXCLUSIVE_LOCK, 0, MAXDWORD, MAXDWORD, &overlap);
+       LockFileEx(db->fp, LOCKFILE_EXCLUSIVE_LOCK, 0, MAXDWORD, MAXDWORD, &overlap);
 #else
-       lockf(fileno(fp), F_LOCK, 0);
+       lockf(fileno(db->fp), F_LOCK, 0);
 #endif
-       fseek(fp, off, SEEK_SET);
-       return false;
+       fseek(db->fp, off, SEEK_SET);
+       db->locked = true;
+       return true;
 }
 
-bool __dw_unlockfile(FILE* fp) {
-       off_t off = ftell(fp);
-       fseek(fp, 0, SEEK_SET);
-       fflush(fp);
+bool __dw_unlockfile(struct dataworks_db* db) {
+       if(!db->locked) {
+               return true;
+       }
+       off_t off = ftell(db->fp);
+       fseek(db->fp, 0, SEEK_SET);
+       fflush(db->fp);
 #if defined(DOS)
 
 #elif defined(__MINGW32__)
        OVERLAPPED overlap = {0};
-       UnlockFileEx(fp, 0, MAXDWORD, MAXDWORD, &overlap);
+       UnlockFileEx(db->fp, 0, MAXDWORD, MAXDWORD, &overlap);
 #else
-       lockf(fileno(fp), F_ULOCK, 0);
+       lockf(fileno(db->fp), F_ULOCK, 0);
 #endif
-       fseek(fp, off, SEEK_SET);
-       return false;
+       fseek(db->fp, off, SEEK_SET);
+       db->locked = false;
+       return true;
 }