/* * Copyright (c) 2009-2023 Julien Nadeau Carriere * 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 AUTHOR 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. */ /* * Database-bound object class. */ #include /* Create a new database-bound object. */ AG_DbObject * AG_DbObjectNew(void) { AG_DbObject *dbo; if ((dbo = TryMalloc(sizeof(AG_DbObject))) == NULL) { return (NULL); } AG_ObjectInit(dbo, &agDbObjectClass); return (dbo); } /* Load the given object's data from the database. */ int AG_DbObjectLoad(void *obj, AG_Db *db, const char *key) { AG_DbObject *dbo = obj; AG_DataSource *ds; AG_DbEntry dbe; AG_OBJECT_ISA(dbo, "AG_DbObject:*"); if (AG_DbLookup(db, &dbe, key) == -1) { return (-1); } if ((ds = AG_OpenCore(dbe.data, dbe.dataSize)) == NULL) { return (-1); } if (AG_ObjectUnserialize(dbo, ds) == -1) { AG_CloseCore(ds); return (-1); } AG_CloseCore(ds); return (0); } /* Save a database-bound object's state. Overwrite data if it exists. */ int AG_DbObjectSave(void *pDbo, AG_Db *db) { AG_DbObject *dbo = pDbo; AG_DataSource *ds; AG_DbEntry dbe; AG_OBJECT_ISA(dbo, "AG_DbObject:*"); if ((ds = AG_OpenAutoCore()) == NULL) return (-1); if (AG_ObjectSerialize(dbo, ds) == -1) goto fail; dbe.key = AGOBJECT(dbo)->name; dbe.keySize = strlen(AGOBJECT(dbo)->name)+1; dbe.data = AG_CORE_SOURCE(ds)->data; dbe.dataSize = AG_CORE_SOURCE(ds)->size; if (AG_DbPut(db, &dbe) == -1 || AG_DbSync(db) == -1) { goto fail; } AG_CloseAutoCore(ds); return (0); fail: AG_CloseAutoCore(ds); return (-1); } /* Insert a new object to the database, fail if key is taken. */ int AG_DbObjectInsert(AG_Db *db, void *pDbo) { AG_DbObject *dbo = pDbo; AG_OBJECT_ISA(dbo, "AG_DbObject:*"); if (AG_DbExists(db, AGOBJECT(dbo)->name)) { AG_SetError("Existing db object: %s", AGOBJECT(dbo)->name); return (-1); } return AG_DbObjectSave(dbo, db); } /* Remove a database object the database by name. */ int AG_DbObjectDelete(AG_Db *db, const char *name) { AG_OBJECT_ISA(dbo, "AG_DbObject:*"); if (AG_DbDelete(db, name) == -1 || AG_DbSync(db) == -1) { return (-1); } return (0); } static void Init(void *_Nonnull obj) { /* Nothing to do */ } AG_ObjectClass agDbObjectClass = { "AG_DbObject", sizeof(AG_DbObject), { 1,0, AGC_DB_OBJECT, 0xE030 }, Init, NULL, /* reset */ NULL, /* destroy */ NULL, /* load */ NULL, /* save */ NULL /* edit */ };