Changeset bff8619 in mainline for uspace/lib/sif/src/sif.c


Ignore:
Timestamp:
2024-08-20T22:07:31Z (2 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
ac9b4f2
Parents:
a3ba37d
Message:

Simplify SIF interface, remove contacts

Remove transactions, move to a load/save model. Remove contacts
application as it was never finished and not useful at all.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/sif/src/sif.c

    ra3ba37d rbff8619  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3333 *
    3434 * Structured Information Format (SIF) is an API that allows an application
    35  * to maintain data in a persistent repository in a format that
    36  *
    37  *  - is structured (and hence extensible)
    38  *  - allows atomic (transactional) updates
    39  *  - allows efficient updates
     35 * to maintain data in a persistent repository in a format that is
     36 * structured (and hence extensible).
    4037 *
    4138 * SIF is meant to be used as the basis for the storage backend used to
     
    4441 * similar to an XML document that contains just tags with attributes
    4542 * (but no text).
    46  *
    47  * SIF can thus naturally express ordered lists (unlike a relational database).
    48  * When contrasted to a (relational) database, SIF is much more primitive.
    49  *
    50  * In particular, SIF
    51  *
    52  *  - does not run on a separate server
    53  *  - des not handle concurrency
    54  *  - does not have a notion of types or data validation
    55  *  - does not understand relations
    56  *  - does not implement any kind of search/queries
    57  *  - does not deal with data sets large enough not to fit in primary memory
    58  *
    59  * any kind of structure data validation is left up to the application.
    6043 */
    6144
     
    172155}
    173156
    174 /** Create and open a SIF repository.
    175  *
    176  * @param fname File name
    177  * @param rsess Place to store pointer to new session.
     157/** Create SIF document.
     158 *
     159 * @param rdoc Place to store pointer to new document.
    178160 *
    179161 * @return EOK on success or error code
    180162 */
    181 errno_t sif_create(const char *fname, sif_sess_t **rsess)
    182 {
    183         sif_sess_t *sess;
     163errno_t sif_new(sif_doc_t **rdoc)
     164{
     165        sif_doc_t *doc;
    184166        sif_node_t *root = NULL;
    185         sif_trans_t *trans = NULL;
    186167        errno_t rc;
    187         FILE *f;
    188 
    189         sess = calloc(1, sizeof(sif_sess_t));
    190         if (sess == NULL)
    191                 return ENOMEM;
    192 
    193         sess->fname = str_dup(fname);
    194         if (sess->fname == NULL) {
    195                 rc = ENOMEM;
    196                 goto error;
    197         }
     168
     169        doc = calloc(1, sizeof(sif_doc_t));
     170        if (doc == NULL)
     171                return ENOMEM;
    198172
    199173        root = sif_node_new(NULL);
     
    209183        }
    210184
    211         f = fopen(fname, "wx");
    212         if (f == NULL) {
    213                 rc = EIO;
    214                 goto error;
    215         }
    216 
    217         sess->f = f;
    218         sess->root = root;
    219 
    220         /* Run a dummy trasaction to marshall initial repo state to file */
    221         rc = sif_trans_begin(sess, &trans);
    222         if (rc != EOK)
    223                 goto error;
    224 
    225         rc = sif_trans_end(trans);
    226         if (rc != EOK)
    227                 goto error;
    228 
    229         *rsess = sess;
     185        doc->root = root;
     186
     187        *rdoc = doc;
    230188        return EOK;
    231189error:
    232         if (trans != NULL)
    233                 sif_trans_abort(trans);
    234190        sif_node_delete(root);
    235         if (sess->fname != NULL)
    236                 free(sess->fname);
    237         free(sess);
     191        free(doc);
    238192        return rc;
    239193}
    240194
    241 /** Open an existing SIF repository.
     195/** Load SIF document.
    242196 *
    243197 * @param fname File name
    244  * @param rsess Place to store pointer to new session.
     198 * @param rdoc Place to store pointer to new document.
    245199 *
    246200 * @return EOK on success or error code
    247201 */
    248 errno_t sif_open(const char *fname, sif_sess_t **rsess)
    249 {
    250         sif_sess_t *sess;
     202errno_t sif_load(const char *fname, sif_doc_t **rdoc)
     203{
     204        sif_doc_t *doc;
    251205        sif_node_t *root = NULL;
    252206        errno_t rc;
    253207        FILE *f;
    254208
    255         sess = calloc(1, sizeof(sif_sess_t));
    256         if (sess == NULL)
    257                 return ENOMEM;
    258 
    259         sess->fname = str_dup(fname);
    260         if (sess->fname == NULL) {
     209        doc = calloc(1, sizeof(sif_doc_t));
     210        if (doc == NULL)
     211                return ENOMEM;
     212
     213        doc->fname = str_dup(fname);
     214        if (doc->fname == NULL) {
    261215                rc = ENOMEM;
    262216                goto error;
     
    278232        }
    279233
    280         sess->root = root;
    281 
    282         sess->f = f;
    283         sess->root = root;
    284         *rsess = sess;
     234        doc->root = root;
     235        *rdoc = doc;
    285236        return EOK;
    286237error:
    287238        sif_node_delete(root);
    288         if (sess->fname != NULL)
    289                 free(sess->fname);
    290         free(sess);
     239        free(doc);
    291240        return rc;
    292241}
    293242
    294 /** Close SIF session.
    295  *
    296  * @param sess SIF session
     243/** Delete SIF document.
     244 *
     245 * @param doc SIF document
    297246 * @return EOK on success or error code
    298247 */
    299 errno_t sif_close(sif_sess_t *sess)
    300 {
    301         sif_node_delete(sess->root);
    302 
    303         if (fclose(sess->f) < 0) {
    304                 free(sess);
    305                 return EIO;
    306         }
    307 
    308         if (sess->fname != NULL)
    309                 free(sess->fname);
    310         free(sess);
    311         return EOK;
     248void sif_delete(sif_doc_t *doc)
     249{
     250        sif_node_delete(doc->root);
     251        free(doc);
    312252}
    313253
    314254/** Return root node.
    315255 *
    316  * @param sess SIF session
    317  */
    318 sif_node_t *sif_get_root(sif_sess_t *sess)
    319 {
    320         return sess->root;
     256 * @param doc SIF document
     257 */
     258sif_node_t *sif_get_root(sif_doc_t *doc)
     259{
     260        return doc->root;
    321261}
    322262
     
    383323}
    384324
    385 /** Begin SIF transaction.
    386  *
    387  * @param trans Transaction
     325/** Save SIF document to file.
     326 * *
     327 * @param doc SIF document
     328 * @param fname File name
    388329 * @return EOK on success or error code
    389330 */
    390 errno_t sif_trans_begin(sif_sess_t *sess, sif_trans_t **rtrans)
    391 {
    392         sif_trans_t *trans;
    393 
    394         trans = calloc(1, sizeof(sif_trans_t));
    395         if (trans == NULL)
    396                 return ENOMEM;
    397 
    398         trans->sess = sess;
    399         *rtrans = trans;
    400         return EOK;
    401 }
    402 
    403 /** Commit SIF transaction.
    404  *
    405  * Commit and free the transaction. If an error is returned, that means
    406  * the transaction has not been freed (and sif_trans_abort() must be used).
    407  *
    408  * @param trans Transaction
    409  * @return EOK on success or error code
    410  */
    411 errno_t sif_trans_end(sif_trans_t *trans)
    412 {
     331errno_t sif_save(sif_doc_t *doc, const char *fname)
     332{
     333        FILE *f = NULL;
    413334        errno_t rc;
    414335
    415         (void) fclose(trans->sess->f);
    416 
    417         trans->sess->f = fopen(trans->sess->fname, "w");
    418         if (trans->sess->f == NULL)
    419                 return EIO;
    420 
    421         rc = sif_export_node(trans->sess->root, trans->sess->f);
     336        f = fopen(fname, "w");
     337        if (f == NULL) {
     338                rc = EIO;
     339                goto error;
     340        }
     341
     342        rc = sif_export_node(doc->root, f);
    422343        if (rc != EOK)
    423                 return rc;
    424 
    425         if (fputc('\n', trans->sess->f) == EOF)
    426                 return EIO;
    427 
    428         if (fflush(trans->sess->f) == EOF)
    429                 return EIO;
    430 
    431         free(trans);
    432         return EOK;
    433 }
    434 
    435 /** Abort SIF transaction.
    436  *
    437  * @param trans Transaction
    438  */
    439 void sif_trans_abort(sif_trans_t *trans)
    440 {
    441         free(trans);
     344                goto error;
     345
     346        if (fputc('\n', f) == EOF) {
     347                rc = EIO;
     348                goto error;
     349        }
     350
     351        if (fflush(f) == EOF) {
     352                rc = EIO;
     353                goto error;
     354        }
     355
     356        return EOK;
     357error:
     358        if (f != NULL)
     359                fclose(f);
     360        return rc;
    442361}
    443362
     
    447366 * @a parent.
    448367 *
    449  * @param trans Transaction
    450368 * @param parent Parent node
    451369 * @param ctype Child type
     
    454372 * @return EOK on success or ENOMEM if out of memory
    455373 */
    456 errno_t sif_node_prepend_child(sif_trans_t *trans, sif_node_t *parent,
    457     const char *ctype, sif_node_t **rchild)
     374errno_t sif_node_prepend_child(sif_node_t *parent, const char *ctype,
     375    sif_node_t **rchild)
    458376{
    459377        sif_node_t *child;
     
    479397 * Create a new child and append it at the end of children list of @a parent.
    480398 *
    481  * @param trans Transaction
    482399 * @param parent Parent node
    483400 * @param ctype Child type
     
    486403 * @return EOK on success or ENOMEM if out of memory
    487404 */
    488 errno_t sif_node_append_child(sif_trans_t *trans, sif_node_t *parent,
    489     const char *ctype, sif_node_t **rchild)
     405errno_t sif_node_append_child(sif_node_t *parent, const char *ctype,
     406    sif_node_t **rchild)
    490407{
    491408        sif_node_t *child;
     
    511428 * Create a new child and insert it before an existing child.
    512429 *
    513  * @param trans Transaction
    514430 * @param sibling Sibling before which to insert
    515431 * @param ctype Child type
     
    518434 * @return EOK on success or ENOMEM if out of memory
    519435 */
    520 errno_t sif_node_insert_before(sif_trans_t *trans, sif_node_t *sibling,
    521     const char *ctype, sif_node_t **rchild)
     436errno_t sif_node_insert_before(sif_node_t *sibling, const char *ctype,
     437    sif_node_t **rchild)
    522438{
    523439        sif_node_t *child;
     
    543459 * Create a new child and insert it after an existing child.
    544460 *
    545  * @param trans Transaction
    546461 * @param sibling Sibling after which to insert
    547462 * @param ctype Child type
     
    550465 * @return EOK on success or ENOMEM if out of memory
    551466 */
    552 errno_t sif_node_insert_after(sif_trans_t *trans, sif_node_t *sibling,
    553     const char *ctype, sif_node_t **rchild)
     467errno_t sif_node_insert_after(sif_node_t *sibling, const char *ctype,
     468    sif_node_t **rchild)
    554469{
    555470        sif_node_t *child;
     
    573488/** Destroy SIF node.
    574489 *
    575  * This function does not return an error, but the transaction may still
    576  * fail to complete.
    577  *
    578  * @param trans Transaction
    579490 * @param node Node to destroy
    580491 */
    581 void sif_node_destroy(sif_trans_t *trans, sif_node_t *node)
     492void sif_node_destroy(sif_node_t *node)
    582493{
    583494        list_remove(&node->lparent);
     
    587498/** Set node attribute.
    588499 *
    589  * @param trans Transaction
    590500 * @param node SIF node
    591501 * @param aname Attribute name
     
    594504 * @return EOK on success, ENOMEM if out of memory
    595505 */
    596 errno_t sif_node_set_attr(sif_trans_t *trans, sif_node_t *node,
    597     const char *aname, const char *avalue)
     506errno_t sif_node_set_attr(sif_node_t *node, const char *aname,
     507    const char *avalue)
    598508{
    599509        odlink_t *link;
     
    636546/** Unset node attribute.
    637547 *
    638  * This function does not return an error, but the transaction may still
    639  * fail to complete.
    640  *
    641  * @param trans Transaction
    642548 * @param node Node
    643549 * @param aname Attribute name
    644550 */
    645 void sif_node_unset_attr(sif_trans_t *trans, sif_node_t *node,
    646     const char *aname)
     551void sif_node_unset_attr(sif_node_t *node, const char *aname)
    647552{
    648553        odlink_t *link;
Note: See TracChangeset for help on using the changeset viewer.