From ee823eeb3d8e09f9b954958644617e77ac898ab9 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Sun, 31 May 2026 01:28:58 +0200 Subject: [PATCH] service: more functions for www<->object --- src/aqcgi/service/0BUILD | 4 + src/aqcgi/service/object.t2d | 75 +++++ src/aqcgi/service/object_html.c | 443 +++++++++++++++++++++++++++ src/aqcgi/service/object_html.h | 20 ++ src/aqcgi/service/objectdef.t2d | 2 +- src/aqcgi/service/objectfielddef.t2d | 28 +- 6 files changed, 565 insertions(+), 7 deletions(-) create mode 100644 src/aqcgi/service/object.t2d create mode 100644 src/aqcgi/service/object_html.c create mode 100644 src/aqcgi/service/object_html.h diff --git a/src/aqcgi/service/0BUILD b/src/aqcgi/service/0BUILD index 2877d29..19fd2d2 100644 --- a/src/aqcgi/service/0BUILD +++ b/src/aqcgi/service/0BUILD @@ -35,6 +35,7 @@ user.t2d session.t2d permdef.t2d + object.t2d objectdef.t2d objectfielddef.t2d @@ -49,6 +50,7 @@ user.h session.h permdef.h + object.h objectdef.h objectfielddef.h @@ -64,6 +66,7 @@ + object_html.h service.h @@ -76,6 +79,7 @@ $(local/typefiles) + object_html.c service.c diff --git a/src/aqcgi/service/object.t2d b/src/aqcgi/service/object.t2d new file mode 100644 index 0000000..6e97f75 --- /dev/null +++ b/src/aqcgi/service/object.t2d @@ -0,0 +1,75 @@ + + + + + + + + AQCGI_OBJECT + AQCGI_Object + object + + + with_xml + with_db + with_list1 + with_list2 + + + +
aqcgi/api.h
+
aqcgi/service/objectdef.h
+
gwenhywfar/error.h
+
+ + + + +
+ + + + + + 0 + 0 + public + with_getbymember sortbymember + + + + 0 + 0 + public + + + + + NULL + NULL + public + own + none + nocopy + + + + NULL + NULL + public + own + + + + NULL + NULL + public + own + + + + +
+ +
+ diff --git a/src/aqcgi/service/object_html.c b/src/aqcgi/service/object_html.c new file mode 100644 index 0000000..c71115d --- /dev/null +++ b/src/aqcgi/service/object_html.c @@ -0,0 +1,443 @@ +/**************************************************************************** + * This file is part of the project AqCGI. + * AqCGI (c) by 2026 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +//#define DISABLE_DEBUGLOG + + +#include "aqcgi/service/object_html.h" + +#include +#include +#include +#include +#include + + + +/* ------------------------------------------------------------------------------------------------ + * defs and enums + * ------------------------------------------------------------------------------------------------ + */ + +#define GBAS GWEN_Buffer_AppendString +#define GBAA GWEN_Buffer_AppendArgs + +#define I18N(msg) msg + + + +/* ------------------------------------------------------------------------------------------------ + * forward declarations + * ------------------------------------------------------------------------------------------------ + */ + +static int _fieldToForm(const AQCGI_OBJECT *o, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf); +static int _writeBool(GWEN_DB_NODE *db, const char *n, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf); +static int _writeInt(GWEN_DB_NODE *db, const char *n, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf); +static int _writeString(GWEN_DB_NODE *db, const char *n, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf); +static int _writeDate(GWEN_DB_NODE *db, const char *n, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf); +static int _writeChoice(GWEN_DB_NODE *db, const char *n, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf); +static int _writeText(const AQCGI_OBJECT *o, GWEN_BUFFER *dbuf); + +static int _fieldFromPostRq(AQCGI_OBJECT *o, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost); +static int _readBool(GWEN_DB_NODE *db, const char *n, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost); +static int _readInt(GWEN_DB_NODE *db, const char *n, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost); +static int _readString(GWEN_DB_NODE *db, const char *n, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost); +static int _readDate(GWEN_DB_NODE *db, const char *n, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost); +static int _readChoice(GWEN_DB_NODE *db, const char *n, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost); +static int _readText(AQCGI_OBJECT *o, GWEN_DB_NODE *dbPost); + + + + +/* ------------------------------------------------------------------------------------------------ + * implementation + * ------------------------------------------------------------------------------------------------ + */ + +int AQCGI_ObjectHtml_toForm(const AQCGI_OBJECT *o, const AQCGI_OBJECT_DEF *odef, GWEN_BUFFER *dbuf) +{ + const AQCGI_FIELD_DEF_LIST *fdefList; + uint32_t flags; + + flags=AQCGI_ObjectDef_GetFlags(odef); + fdefList=AQCGI_ObjectDef_GetFieldDefList(odef); + if (fdefList && AQCGI_FieldDef_List_GetCount(fdefList)) { + const AQCGI_FIELD_DEF *fdef; + + GBAS(dbuf,"\n"); + fdef=AQCGI_FieldDef_List_First(fdefList); + while(fdef) { + int rv; + + rv=_fieldToForm(o, odef, fdef, dbuf); + if (rv<0) { + DBG_INFO(AQCGI_LOGDOMAIN, "here (%d)", rv); + return rv; + } + + fdef=AQCGI_FieldDef_List_Next(fdef); + } + + + GBAS(dbuf,"
\n"); + } + if (flags & AQCGI_OBJECT_FLAGS_HASTEXT) + _writeText(o, dbuf); + + return 0; +} + + + +int AQCGI_ObjectHtml_fromPostRq(AQCGI_OBJECT *o, const AQCGI_OBJECT_DEF *odef, GWEN_DB_NODE *dbPost) +{ + const AQCGI_FIELD_DEF_LIST *fdefList; + uint32_t flags; + + flags=AQCGI_ObjectDef_GetFlags(odef); + fdefList=AQCGI_ObjectDef_GetFieldDefList(odef); + if (fdefList && AQCGI_FieldDef_List_GetCount(fdefList)) { + const AQCGI_FIELD_DEF *fdef; + + fdef=AQCGI_FieldDef_List_First(fdefList); + while(fdef) { + int rv; + + rv=_fieldFromPostRq(o, odef, fdef, dbPost); + if (rv<0) { + DBG_INFO(AQCGI_LOGDOMAIN, "here (%d)", rv); + return rv; + } + + fdef=AQCGI_FieldDef_List_Next(fdef); + } + } + if (flags & AQCGI_OBJECT_FLAGS_HASTEXT) + _readText(o, dbPost); + + return 0; +} + + + + + + + + +int _fieldToForm(const AQCGI_OBJECT *o, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf) +{ + GWEN_DB_NODE *db; + + db=AQCGI_Object_GetVars(o); + if (db) { + int t; + int rv=GWEN_ERROR_GENERIC; + const char *sName; + const char *sLabel; + + /* write label */ + sName=AQCGI_FieldDef_GetName(fdef); + sLabel=AQCGI_FieldDef_GetLabel(fdef); + GBAA(dbuf, "", sName?sName:"", sLabel?sLabel:""); + + /* write field */ + t=AQCGI_FieldDef_GetDataType(fdef); + switch(t) { + case AQCGI_ObjectFieldType_Unknown: rv=GWEN_ERROR_BAD_DATA; break; + case AQCGI_ObjectFieldType_Bool: rv=_writeBool(db, sName, odef, fdef, dbuf); break; + case AQCGI_ObjectFieldType_Int: rv=_writeInt(db, sName, odef, fdef, dbuf); break; + case AQCGI_ObjectFieldType_String: rv=_writeString(db, sName, odef, fdef, dbuf); break; + case AQCGI_ObjectFieldType_Date: rv=_writeDate(db, sName, odef, fdef, dbuf); break; + case AQCGI_ObjectFieldType_Choice: rv=_writeChoice(db, sName, odef, fdef, dbuf); break; + + } + GBAS(dbuf, "\n"); + + return rv; + } + else { + DBG_ERROR(AQCGI_LOGDOMAIN, "No vars"); + return GWEN_ERROR_NO_DATA; + } +} + + + +int _writeBool(GWEN_DB_NODE *db, const char *sName, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf) +{ + int v; + + v=GWEN_DB_GetIntValue(db, sName, 0, 0); + GBAA(dbuf, "", sName, v?"checked":""); + return 0; +} + + + +int _writeInt(GWEN_DB_NODE *db, const char *sName, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf) +{ + int v; + uint32_t flags; + + flags=AQCGI_FieldDef_GetFlags(fdef); + v=GWEN_DB_GetIntValue(db, sName, 0, 0); + GBAA(dbuf, ""); + return 0; +} + + + +int _writeString(GWEN_DB_NODE *db, const char *sName, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf) +{ + const char *v; + uint32_t flags; + + flags=AQCGI_FieldDef_GetFlags(fdef); + v=GWEN_DB_GetCharValue(db, sName, 0, NULL); + GBAA(dbuf, ""); + return 0; +} + + + +int _writeDate(GWEN_DB_NODE *db, const char *sName, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf) +{ + int64_t v; + GWEN_TIMESTAMP *ts; + GWEN_DATE *dt; + + v=(int64_t) GWEN_DB_GetIntValue(db, sName, 0, 0); + ts=GWEN_Timestamp_fromInt64(v); + dt=ts?GWEN_Date_fromLocalTime(GWEN_Timestamp_toTimeT(ts)):GWEN_Date_CurrentDate(); + GWEN_Timestamp_free(ts); + GBAA(dbuf, ""); + GWEN_Date_free(dt); + return 0; +} + + + +int _writeChoice(GWEN_DB_NODE *db, const char *sName, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_BUFFER *dbuf) +{ + int v; + const char *sChoices; + + v=GWEN_DB_GetIntValue(db, sName, 0, 0); + sChoices=AQCGI_FieldDef_GetChoices(fdef); + if (sChoices && *sChoices) { + GWEN_STRINGLIST *sl; + + sl=GWEN_StringList_fromString2(sChoices, ";", 0, GWEN_TEXT_FLAGS_DEL_QUOTES | GWEN_TEXT_FLAGS_CHECK_BACKSLASH); + if (sl) { + GWEN_STRINGLISTENTRY *se; + int i=0; + + GBAA(dbuf, "\n"); + return 0; +} + + + + + + +int _fieldFromPostRq(AQCGI_OBJECT *o, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost) +{ + GWEN_DB_NODE *db; + int t; + int rv=GWEN_ERROR_GENERIC; + const char *sName; + + db=AQCGI_Object_GetVars(o); + if (db==NULL) { + db=GWEN_DB_Group_new("vars"); + AQCGI_Object_SetVars(o, db); + } + + sName=AQCGI_FieldDef_GetName(fdef); + + /* read field */ + t=AQCGI_FieldDef_GetDataType(fdef); + switch(t) { + case AQCGI_ObjectFieldType_Unknown: rv=GWEN_ERROR_BAD_DATA; break; + case AQCGI_ObjectFieldType_Bool: rv=_readBool(db, sName, odef, fdef, dbPost); break; + case AQCGI_ObjectFieldType_Int: rv=_readInt(db, sName, odef, fdef, dbPost); break; + case AQCGI_ObjectFieldType_String: rv=_readString(db, sName, odef, fdef, dbPost); break; + case AQCGI_ObjectFieldType_Date: rv=_readDate(db, sName, odef, fdef, dbPost); break; + case AQCGI_ObjectFieldType_Choice: rv=_readChoice(db, sName, odef, fdef, dbPost); break; + } + + return rv; +} + + + +int _readBool(GWEN_DB_NODE *db, const char *sName, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost) +{ + const char *v; + + v=GWEN_DB_GetCharValue(dbPost, sName, 0, NULL); + GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, sName, v?1:0); + return 0; +} + + + +int _readInt(GWEN_DB_NODE *db, const char *sName, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost) +{ + int v; + + v=GWEN_DB_GetIntValue(dbPost, sName, 0, 0); + GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, sName, v); + return 0; +} + + + +int _readString(GWEN_DB_NODE *db, const char *sName, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost) +{ + const char *v; + + v=GWEN_DB_GetCharValue(dbPost, sName, 0, NULL); + if (v && *v) + GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, sName, v); + else + GWEN_DB_DeleteVar(db, sName); + return 0; +} + + + +int _readDate(GWEN_DB_NODE *db, const char *sName, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost) +{ + const char *v; + int64_t i=0; + + v=GWEN_DB_GetCharValue(dbPost, sName, 0, NULL); + if (v && *v) { + GWEN_DATE *dt; + + dt=GWEN_Date_fromStringWithTemplate(v, "YYYY-MM-DD"); + if (dt) { + GWEN_TIMESTAMP *ts; + + ts=GWEN_Timestamp_fromLocalTime(GWEN_Date_toLocalTime(dt)); + i=ts?GWEN_Timestamp_toInt64(ts):0; + GWEN_Timestamp_free(ts); + GWEN_Date_free(dt); + } + } + GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, sName, i); + return 0; +} + + + +int _readChoice(GWEN_DB_NODE *db, const char *sName, const AQCGI_OBJECT_DEF *odef, const AQCGI_FIELD_DEF *fdef, GWEN_DB_NODE *dbPost) +{ + const char *v; + int i=0; + + v=GWEN_DB_GetCharValue(dbPost, sName, 0, NULL); + if (v && *v) { + const char *sChoices; + + sChoices=AQCGI_FieldDef_GetChoices(fdef); + if (sChoices && *sChoices) { + GWEN_STRINGLIST *sl; + + sl=GWEN_StringList_fromString2(sChoices, ";", 0, GWEN_TEXT_FLAGS_DEL_QUOTES | GWEN_TEXT_FLAGS_CHECK_BACKSLASH); + if (sl) { + GWEN_STRINGLISTENTRY *se; + int i=0; + + se=GWEN_StringList_FirstEntry(sl); + while(se) { + const char *s; + + s=GWEN_StringListEntry_Data(se); + if (s && *s && strcasecmp(s, v)==0) + break; + i++; + se=GWEN_StringListEntry_Next(se); + } + GWEN_StringList_free(sl); + } + } + } + GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, sName, i); + return 0; +} + + + +int _readText(AQCGI_OBJECT *o, GWEN_DB_NODE *dbPost) +{ + const char *v; + + v=GWEN_DB_GetCharValue(dbPost, "text", 0, NULL); + AQCGI_Object_SetText(o, v); + return 0; +} + + + + + + + + + diff --git a/src/aqcgi/service/object_html.h b/src/aqcgi/service/object_html.h new file mode 100644 index 0000000..6cf1f43 --- /dev/null +++ b/src/aqcgi/service/object_html.h @@ -0,0 +1,20 @@ +/**************************************************************************** + * This file is part of the project AqCGI. + * AqCGI (c) by 2026 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQCGI_SERVICE_OBJECT_HTML_H +#define AQCGI_SERVICE_OBJECT_HTML_H + + +#include "aqcgi/service/object.h" +#include "aqcgi/service/objectdef.h" + + + + +#endif + diff --git a/src/aqcgi/service/objectdef.t2d b/src/aqcgi/service/objectdef.t2d index e74d626..94bb6b3 100644 --- a/src/aqcgi/service/objectdef.t2d +++ b/src/aqcgi/service/objectdef.t2d @@ -57,7 +57,7 @@ with_flags - + NULL NULL public diff --git a/src/aqcgi/service/objectfielddef.t2d b/src/aqcgi/service/objectfielddef.t2d index 9cf21bf..d2b6c99 100644 --- a/src/aqcgi/service/objectfielddef.t2d +++ b/src/aqcgi/service/objectfielddef.t2d @@ -1,12 +1,12 @@ - + - AQCGI_OBJECT_FIELD_DEF - AQCGI_ObjectFieldDef + AQCGI_FIELD_DEF + AQCGI_FieldDef objectfielddef @@ -27,15 +27,17 @@ - + + + - + boolean @@ -67,7 +69,7 @@ 0 0 public - own + own with_getbymember @@ -91,6 +93,20 @@ + + 0 + 0 + public + + + + + 0 + 0 + public + + + Semicolon separated list of choices 0