]> Nishi Git Mirror - dataworks.git/commitdiff
can create table now
authornishi <nishi@d4a5a174-5a4a-5b4b-b672-37683c10d7d5>
Wed, 22 May 2024 03:24:38 +0000 (03:24 +0000)
committernishi <nishi@d4a5a174-5a4a-5b4b-b672-37683c10d7d5>
Wed, 22 May 2024 03:24:38 +0000 (03:24 +0000)
git-svn-id: file:///raid/svn-main/nishi-dataworks/trunk@67 d4a5a174-5a4a-5b4b-b672-37683c10d7d5

Client/main.c
FORMATv1.md
Library/Makefile
Library/database.c
Library/database_table.c [new file with mode: 0644]
Library/dw_database.h
Library/util.c

index 3eeb4b70998517e5daddaedac1977183d4022a7f..062d1081358acfc16e8aed65525f9676c05cc690 100644 (file)
@@ -123,7 +123,7 @@ int main(int argc, char** argv) {
        struct tm* tm = localtime(&mtime);
        char mtimestr[256];
        strftime(mtimestr, 255, "%a %b %d %H:%M:%S %Z %Y", tm);
-       printf("Opened the database (Version %d, Modified at %s).\n", dataworks_database_get_version(db), mtimestr);
+       printf("Opened the database (Version %d, Modified at %s).\n", dataworks_database_get_version(db), mtimestr);    
        printf("\n");
        printf("Type a command (.help) for the help.\n");
        printf("\n");
@@ -160,7 +160,7 @@ int main(int argc, char** argv) {
                                                int i;
                                                for(i = 0; list[i] != NULL; i++)
                                                        ;
-                                               printf("%d tables found.\n", i);
+                                               printf("%d table(s) found.\n", i);
                                                for(i = 0; list[i] != NULL; i++) {
                                                        printf("  %s\n", list[i]);
                                                        free(list[i]);
index b287f5928cf0c939fad558aa89a5efdc807d3fc7..3da0874d7b4dfa59a50b46443c6da6dcb93bf0cf 100644 (file)
@@ -18,7 +18,6 @@ Database entry (`dbentry`) MUST be in this format:
 | ---- | ---- | ---- | ---- |
 | length | 4 bytes | uint32\_t | Size of the entry |
 | size | 4 bytes | uint32\_t | |
-| type | 1 byte | ASCII | |
 | flag | 1 byte | uint8\_t | |
 | field\_index | 1 byte | uint8\_t | |
 | db\_index | 1 byte | uint8\_t | |
@@ -26,15 +25,6 @@ Database entry (`dbentry`) MUST be in this format:
 | fragnum | 8 bytes | uint64\_t | |
 | data | \[size\] bytes | ASCII | |
 
-There are 5 types for `dbentry`:
-| Type | Character | Type | Info |
-| ---- | --------- | ---- | ---- |
-| String | `S` | ASCII | |
-| Integer | `I` | uint64\_t | |
-| Double | `D` | double | |
-| Logical | `L` | uint8\_t | 0 for false, other value for true |
-| Help | `?` | ASCII | Should be just ignored |
-
 and 2 flags for `dbentry`:
 | Type | Mask | Info |
 | ---- | ---- | ---- |
@@ -48,7 +38,16 @@ Index entry (`indexentry`) MUST be in this format:
 | count | 8 bytes | uint64\_t | |
 | dbname\_len | 1 byte | uint8\_t | |
 | dbname | 256 bytes | ASCII | |
-| fields | 4096 bytes | ASCII | Separate field names using NUL. Put NUL twice on the last field name. |
+| fields | 4096 bytes | ASCII | Separate field names using NUL. Put NUL twice on the last field name. Like: `type` `name` `<NUL>` `type` `name` `<NUL>` ... `type` `name` `<NUL>` `<NUL>` |
+
+There are 5 types for `indexentry`:
+| Type | Character | Type | Info |
+| ---- | --------- | ---- | ---- |
+| String | `S` | ASCII | |
+| Integer | `I` | uint64\_t | |
+| Double | `D` | double | |
+| Logical | `L` | uint8\_t | 0 for false, other value for true |
+| Help | `?` | ASCII | Should be just ignored |
 
 There is 1 flag for `indexentry`:
 | Type | Mask | Info |
index c033494ee52515d7273fc513980a01d5e90ac84c..e11800ae2196a5bd0551f44e8858678d10b7dba1 100644 (file)
@@ -3,7 +3,7 @@
 .PHONY: all clean
 .SUFFIXES: .c .o
 
-OBJS = parser.o database.o util.o dataworks.o
+OBJS = parser.o database.o util.o dataworks.o database_table.o
 
 all: $(LIB_PREFIX)dataworks$(LIB_SUFFIX) $(STATICLIB_PREFIX)dataworks$(STATICLIB_SUFFIX)
 
index a55072079721643ae023d5e1c28048245d0216bf..f0e07daa08e952df52b35a0c2df76d4e23d4cfdc 100644 (file)
@@ -119,49 +119,6 @@ int dataworks_database_get_version(struct dataworks_db* db) { return db->version
 
 uint64_t dataworks_database_get_mtime(struct dataworks_db* db) { return db->mtime; }
 
-#define buffer_to_db_v1_indexentry(buf, index) \
-       memcpy(&index.flag, buf, 1); \
-       uint64_t be_count; \
-       memcpy(&be_count, buf + 1, 8); \
-       __dw_native_endian(be_count, uint64_t, index.count = __converted); \
-       memcpy(&index.dbname_len, buf + 1 + 8, 1); \
-       memcpy(index.dbname, buf + 1 + 8 + 1, 256); \
-       memcpy(index.fields, buf + 1 + 8 + 1 + 256, 4096);
+const char* dw_errors[] = {"Success", "Used already"};
 
-char** dataworks_database_get_table_list(struct dataworks_db* db) {
-       if(db->version == 1) {
-               __dw_lockfile(db->fp);
-               fseek(db->fp, sizeof(sig) + 10, SEEK_SET);
-               int i;
-               struct dataworks_db_v1_indexentry index;
-               char* buf = malloc(1 + 8 + 1 + 256 + 4096);
-               int c = 0;
-               for(i = 0; i < 256; i++) {
-                       fread(buf, 1, 1 + 8 + 1 + 256 + 4096, db->fp);
-                       buffer_to_db_v1_indexentry(buf, index);
-                       if(index.flag & DATAWORKS_V1_INDEXENTRY_USED) {
-                               c++;
-                       }
-               }
-               char** list = malloc(sizeof(*list) * (c + 1));
-               fseek(db->fp, sizeof(sig) + 10, SEEK_SET);
-               c = 0;
-               for(i = 0; i < 256; i++) {
-                       fread(buf, 1, 1 + 8 + 1 + 256 + 4096, db->fp);
-                       buffer_to_db_v1_indexentry(buf, index);
-                       if(index.flag & DATAWORKS_V1_INDEXENTRY_USED) {
-                               list[c] = malloc(index.dbname_len + 1);
-                               memcpy(list[c], index.dbname, index.dbname_len);
-                               list[c][index.dbname_len] = 0;
-                               c++;
-                       }
-               }
-               list[c] = NULL;
-               free(buf);
-               __dw_unlockfile(db->fp);
-               return list;
-       } else {
-               /* Not implemented for the version */
-               return NULL;
-       }
-}
+const char* dataworks_database_strerror(int n) { return dw_errors[n]; }
diff --git a/Library/database_table.c b/Library/database_table.c
new file mode 100644 (file)
index 0000000..bc2cd58
--- /dev/null
@@ -0,0 +1,120 @@
+/* $Id$ */
+/* --- START LICENSE --- */
+/* -------------------------------------------------------------------------- */
+/* Copyright (c) 2024 Nishi.                                                  */
+/* Redistribution and use in source and binary forms, with or without modific */
+/* ation, are permitted provided that the following conditions are met:       */
+/*     1. Redistributions of source code must retain the above copyright noti */
+/* ce, this list of conditions and the following disclaimer.                  */
+/*     2. Redistributions in binary form must reproduce the above copyright n */
+/* otice, this list of conditions and the following disclaimer in the documen */
+/* tation and/or other materials provided with the distribution.              */
+/*     3. Neither the name of the copyright holder nor the names of its contr */
+/* ibutors may be used to endorse or promote products derived from this softw */
+/* are 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, TH */
+/* E IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPO */
+/* SE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS  */
+/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CON */
+/* SEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITU */
+/* TE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPT */
+/* ION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S */
+/* TRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN AN */
+/* Y WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY  */
+/* OF SUCH DAMAGE.                                                            */
+/* -------------------------------------------------------------------------- */
+/* --- END LICENSE --- */
+
+#include "dw_database.h"
+
+#include "dw_util.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+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);
+               fseek(db->fp, 3 + 10, SEEK_SET);
+               int i;
+               struct dataworks_db_v1_indexentry index;
+               char* buf = malloc(1 + 8 + 1 + 256 + 4096);
+               for(i = 0; i < 256; i++) {
+                       fread(buf, 1, 1 + 8 + 1 + 256 + 4096, db->fp);
+                       __dw_buffer_to_db_v1_indexentry(buf, index);
+                       if(index.flag & DATAWORKS_V1_INDEXENTRY_USED) {
+                               char* dbname = malloc(index.dbname_len + 1);
+                               memcpy(dbname, index.dbname, index.dbname_len);
+                               dbname[index.dbname_len] = 0;
+                               if(strcmp(name, dbname) == 0) {
+                                       free(dbname);
+                                       free(buf);
+                                       __dw_unlockfile(db->fp);
+                                       return DW_ERR_USED;
+                               }
+                       }
+               }
+               fseek(db->fp, 3 + 10, SEEK_SET);
+               for(i = 0; i < 256; i++) {
+                       fread(buf, 1, 1 + 8 + 1 + 256 + 4096, db->fp);
+                       __dw_buffer_to_db_v1_indexentry(buf, index);
+                       if(!(index.flag & DATAWORKS_V1_INDEXENTRY_USED)) {
+                               fseek(db->fp, -(1 + 8 + 1 + 256 + 4096), SEEK_CUR);
+                               buf[0] |= DATAWORKS_V1_INDEXENTRY_USED;
+                               buf[8 + 1] = strlen(name);
+                               memcpy(buf + 1 + 8 + 1, name, strlen(name));
+                               fwrite(buf, 1, 1 + 8 + 1 + 256, db->fp);
+                               int j;
+                               for(j = 0; fieldtypes[j] != 0; j++) {
+                                       fwrite(fieldtypes + j, 1, 1, db->fp);
+                                       fwrite(fields[j], 1, strlen(fields[j]), db->fp);
+                                       fwrite("\0", 1, 1, db->fp);
+                               }
+                               fwrite("\0", 1, 1, db->fp);
+                               break;
+                       }
+               }
+               free(buf);
+               __dw_unlockfile(db->fp);
+       }
+}
+
+char** dataworks_database_get_table_list(struct dataworks_db* db) {
+       if(db->version == 1) {
+               __dw_lockfile(db->fp);
+               fseek(db->fp, 3 + 10, SEEK_SET);
+               int i;
+               struct dataworks_db_v1_indexentry index;
+               char* buf = malloc(1 + 8 + 1 + 256 + 4096);
+               int c = 0;
+               for(i = 0; i < 256; i++) {
+                       fread(buf, 1, 1 + 8 + 1 + 256 + 4096, db->fp);
+                       __dw_buffer_to_db_v1_indexentry(buf, index);
+                       if(index.flag & DATAWORKS_V1_INDEXENTRY_USED) {
+                               c++;
+                       }
+               }
+               char** list = malloc(sizeof(*list) * (c + 1));
+               fseek(db->fp, 3 + 10, SEEK_SET);
+               c = 0;
+               for(i = 0; i < 256; i++) {
+                       fread(buf, 1, 1 + 8 + 1 + 256 + 4096, db->fp);
+                       __dw_buffer_to_db_v1_indexentry(buf, index);
+                       if(index.flag & DATAWORKS_V1_INDEXENTRY_USED) {
+                               list[c] = malloc(index.dbname_len + 1);
+                               memcpy(list[c], index.dbname, index.dbname_len);
+                               list[c][index.dbname_len] = 0;
+                               c++;
+                       }
+               }
+               list[c] = NULL;
+               free(buf);
+               __dw_unlockfile(db->fp);
+               return list;
+       } else {
+               /* Not implemented for the version */
+               return NULL;
+       }
+}
index 7777781ae7d6fc4dc60203d12506efe08012d6b5..b8ee6a6b1514a8b05151e7a1487ff2029e005fee 100644 (file)
@@ -49,6 +49,35 @@ extern "C" {
 #define PACKED __attribute__((__packed__))
 #endif
 
+#define __dw_buffer_to_db_v1_indexentry(buf, index) \
+       memcpy(&index.flag, buf, 1); \
+       uint64_t be_count; \
+       memcpy(&be_count, buf + 1, 8); \
+       __dw_native_endian(be_count, uint64_t, index.count = __converted); \
+       memcpy(&index.dbname_len, buf + 1 + 8, 1); \
+       memcpy(index.dbname, buf + 1 + 8 + 1, 256); \
+       memcpy(index.fields, buf + 1 + 8 + 1 + 256, 4096);
+
+/**
+ * @~english
+ * @brief Error enum
+ *
+ */
+enum DW_ERRORS {
+       /**
+        * @~english
+        * @brief Success
+        *
+        */
+       DW_ERR_SUCCESS = 0,
+       /**
+        * @~english
+        * @brief Used already
+        *
+        */
+       DW_ERR_USED
+};
+
 /**
  * @~english
  * @brief Database struct
@@ -155,11 +184,34 @@ uint64_t dataworks_database_get_mtime(struct dataworks_db* db);
  * @~english
  * @brief Get the table list of the database.
  * @param db Database
- * @return Table list of the databas
+ * @return Table list of the database
  *
  */
 char** dataworks_database_get_table_list(struct dataworks_db* db);
 
+/**
+ * @~english
+ * @brief Creates a table.
+ * @param db Database
+ * @param name Table name
+ * @param fields Fields
+ * @param fieldtypes Types
+ * @return
+ * - `0` if success
+ * - `DW_ERR_USED` if the name is already used
+ *
+ */
+int dataworks_database_create_table(struct dataworks_db* db, const char* name, char** fields, const char* fieldtypes);
+
+/**
+ * @~english
+ * @brief Converts error number to a string.
+ * @param n Error number
+ * @return Error string
+ *
+ */
+const char* dataworks_database_strerror(int n);
+
 #ifdef __cplusplus
 }
 #endif
index 554ea12fc336f76f43839ac93c6cadbc67ef145e..b66e809d81e4779ffe53a35475623bdb94f6cca4 100644 (file)
@@ -72,6 +72,7 @@ bool __dw_lockfile(FILE* fp) {
 bool __dw_unlockfile(FILE* fp) {
        off_t off = ftell(fp);
        fseek(fp, 0, SEEK_SET);
+       fflush(fp);
 #if defined(DOS)
 
 #elif defined(__MINGW32__)