src/valhalla.c
author Mathieu Schroeter <mathieu.schroeter@mycable.ch>
Sat Feb 27 20:06:09 2010 +0100 (12 days ago)
changeset 972 72b9ec6075d7
parent 957e7faa9d50198
permissions -rw-r--r--
avoid strcmp with the check for null string
     1 /*
     2  * GeeXboX Valhalla: tiny media scanner API.
     3  * Copyright (C) 2009-2010 Mathieu Schroeter <mathieu.schroeter@gamesover.ch>
     4  *
     5  * This file is part of libvalhalla.
     6  *
     7  * libvalhalla is free software; you can redistribute it and/or
     8  * modify it under the terms of the GNU Lesser General Public
     9  * License as published by the Free Software Foundation; either
    10  * version 2.1 of the License, or (at your option) any later version.
    11  *
    12  * libvalhalla is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    15  * Lesser General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU Lesser General Public
    18  * License along with libvalhalla; if not, write to the Free Software
    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    20  */
    21 
    22 #include <pthread.h>
    23 #include <stdlib.h>
    24 #include <string.h>
    25 
    26 #ifdef USE_LAVC
    27 #include <libavcodec/avcodec.h>
    28 #endif /* USE_LAVC */
    29 #include <libavformat/avformat.h>
    30 
    31 #include "valhalla.h"
    32 #include "valhalla_internals.h"
    33 #include "parser.h"
    34 #include "scanner.h"
    35 #include "dbmanager.h"
    36 #include "dispatcher.h"
    37 #include "ondemand.h"
    38 #include "event_handler.h"
    39 #include "utils.h"
    40 #include "osdep.h"
    41 #include "stats.h"
    42 #include "metadata.h"
    43 #include "logs.h"
    44 
    45 #ifdef USE_GRABBER
    46 #include "grabber.h"
    47 #include "downloader.h"
    48 #include "url_utils.h"
    49 #endif /* USE_GRABBER */
    50 
    51 static int g_preinit;
    52 static pthread_mutex_t g_preinit_mutex = PTHREAD_MUTEX_INITIALIZER;
    53 
    54 
    55 unsigned int
    56 libvalhalla_version (void)
    57 {
    58   return LIBVALHALLA_VERSION_INT;
    59 }
    60 
    61 /******************************************************************************/
    62 /*                                                                            */
    63 /*                             Valhalla Handling                              */
    64 /*                                                                            */
    65 /******************************************************************************/
    66 
    67 static void
    68 queue_cleanup (fifo_queue_t *queue)
    69 {
    70   int e;
    71   void *data;
    72 
    73   vh_fifo_queue_push (queue,
    74                       FIFO_QUEUE_PRIORITY_NORMAL, ACTION_CLEANUP_END, NULL);
    75 
    76   do
    77   {
    78     e = ACTION_NO_OPERATION;
    79     data = NULL;
    80     vh_fifo_queue_pop (queue, &e, &data);
    81 
    82     switch (e)
    83     {
    84     default:
    85       break;
    86 
    87     case ACTION_DB_INSERT_P:
    88     case ACTION_DB_INSERT_G:
    89     case ACTION_DB_UPDATE_P:
    90     case ACTION_DB_UPDATE_G:
    91     case ACTION_DB_END:
    92     case ACTION_DB_NEWFILE:
    93       if (data)
    94         vh_file_data_free (data);
    95       break;
    96 
    97     case ACTION_DB_EXT_INSERT:
    98     case ACTION_DB_EXT_UPDATE:
    99     case ACTION_DB_EXT_DELETE:
   100       if (data)
   101         vh_dbmanager_extmd_free (data);
   102       break;
   103 
   104     case ACTION_OD_ENGAGE:
   105     case ACTION_EH_EVENTGL:
   106       if (data)
   107         free (data);
   108       break;
   109 
   110     case ACTION_EH_EVENTOD:
   111       if (data)
   112         vh_event_handler_od_free (data);
   113       break;
   114 
   115     case ACTION_EH_EVENTMD:
   116       if (data)
   117         vh_event_handler_md_free (data);
   118       break;
   119     }
   120   }
   121   while (e != ACTION_CLEANUP_END);
   122 }
   123 
   124 static void
   125 valhalla_mrproper (valhalla_t *handle)
   126 {
   127   unsigned int i;
   128   fifo_queue_t *fifo_o;
   129 
   130   fifo_queue_t *fifo_i[] = {
   131     vh_scanner_fifo_get (handle->scanner),
   132     vh_dbmanager_fifo_get (handle->dbmanager),
   133     vh_dispatcher_fifo_get (handle->dispatcher),
   134     vh_parser_fifo_get (handle->parser),
   135 #ifdef USE_GRABBER
   136     vh_grabber_fifo_get (handle->grabber),
   137     vh_downloader_fifo_get (handle->downloader),
   138 #endif /* USE_GRABBER */
   139     vh_event_handler_fifo_get (handle->event_handler),
   140   };
   141 
   142   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   143 
   144   if (!handle)
   145     return;
   146 
   147   fifo_o = vh_fifo_queue_new ();
   148   if (!fifo_o)
   149     return;
   150 
   151 #ifdef USE_GRABBER
   152   vh_dbmanager_db_begin_transaction (handle->dbmanager);
   153 
   154   /* remove all previous contexts */
   155   vh_dbmanager_db_dlcontext_delete (handle->dbmanager);
   156 #endif /* USE_GRABBER */
   157 
   158   /*
   159    * The same data pointer can exist in several queues at the same time.
   160    * The goal is to identify all unique entries from all queues and to save
   161    * these entries in the fifo_o queue.
   162    * Then, all data pointers can be safety freed (prevents double free).
   163    */
   164   for (i = 0; i < ARRAY_NB_ELEMENTS (fifo_i); i++)
   165   {
   166     int e;
   167     void *data;
   168 
   169     if (!fifo_i[i])
   170       continue;
   171 
   172     vh_fifo_queue_push (fifo_i[i],
   173                         FIFO_QUEUE_PRIORITY_NORMAL, ACTION_CLEANUP_END, NULL);
   174 
   175     do
   176     {
   177       e = ACTION_NO_OPERATION;
   178       data = NULL;
   179       vh_fifo_queue_pop (fifo_i[i], &e, &data);
   180 
   181       switch (e)
   182       {
   183       case ACTION_DB_INSERT_P:
   184       case ACTION_DB_INSERT_G:
   185       case ACTION_DB_UPDATE_P:
   186       case ACTION_DB_UPDATE_G:
   187       case ACTION_DB_END:
   188       case ACTION_DB_NEWFILE:
   189       {
   190         file_data_t *file = data;
   191         if (!file || file->clean_f)
   192           break;
   193 
   194         file->clean_f = 1;
   195         vh_fifo_queue_push (fifo_o, FIFO_QUEUE_PRIORITY_NORMAL, e, data);
   196 
   197 #ifdef USE_GRABBER
   198         /* save downloader context */
   199         if (file->step < STEP_ENDING && file->list_downloader)
   200           vh_dbmanager_db_dlcontext_save (handle->dbmanager, file);
   201 #endif /* USE_GRABBER */
   202         break;
   203       }
   204 
   205       case ACTION_DB_EXT_INSERT:
   206       case ACTION_DB_EXT_UPDATE:
   207       case ACTION_DB_EXT_DELETE:
   208       case ACTION_EH_EVENTOD:
   209       case ACTION_EH_EVENTMD:
   210       case ACTION_EH_EVENTGL:
   211         vh_fifo_queue_push (fifo_o, FIFO_QUEUE_PRIORITY_NORMAL, e, data);
   212         break;
   213 
   214       default:
   215         break;
   216       }
   217     }
   218     while (e != ACTION_CLEANUP_END);
   219   }
   220 
   221 #ifdef USE_GRABBER
   222   vh_dbmanager_db_end_transaction (handle->dbmanager);
   223 #endif /* USE_GRABBER */
   224 
   225   queue_cleanup (fifo_o);
   226   vh_fifo_queue_free (fifo_o);
   227 
   228   /* On-demand queue must be handled separately. */
   229   fifo_o = vh_ondemand_fifo_get (handle->ondemand);
   230   if (!fifo_o)
   231     return;
   232   queue_cleanup (fifo_o);
   233 }
   234 
   235 int
   236 valhalla_config_set_orig (valhalla_t *handle, valhalla_cfg_t conf, ...)
   237 {
   238   int res = 0;
   239   const void *p1 = NULL, *p2 = NULL;
   240   int i = 0;
   241 
   242   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   243 
   244   if (!handle)
   245     return -1;
   246 
   247   if (conf >= (1 << VH_CFG_RANGE))
   248   {
   249     va_list ap;
   250 
   251     va_start (ap, conf);
   252 
   253     if (conf & VH_VOIDP_T)
   254       p1 = va_arg (ap, void *);
   255     if (conf & VH_INT_T)
   256       i  = va_arg (ap, int);
   257     if (conf & VH_VOIDP_2_T)
   258       p2 = va_arg (ap, void *);
   259 
   260     if (va_arg (ap, int) != ~0) /* check for safeguard */
   261     {
   262       vh_log (VALHALLA_MSG_CRITICAL,
   263               "unrecoverable error with valhalla_config_set(), conf = %#x, "
   264               "it is probably a bad use of this function", conf);
   265       res = -2;
   266     }
   267 
   268     va_end (ap);
   269   }
   270 
   271   if (res)
   272     return res;
   273 
   274   switch (conf)
   275   {
   276 #ifdef USE_GRABBER
   277   case VALHALLA_CFG_DOWNLOADER_DEST:
   278     vh_downloader_destination_set (handle->downloader, (valhalla_dl_t) i, p1);
   279     break;
   280 
   281   case VALHALLA_CFG_GRABBER_PRIORITY:
   282     vh_grabber_priority_set (handle->grabber,
   283                              p1, (valhalla_metadata_pl_t) i, p2);
   284     break;
   285 
   286   case VALHALLA_CFG_GRABBER_STATE:
   287     if (p1)
   288       vh_grabber_state_set (handle->grabber, p1, i);
   289     break;
   290 #endif /* USE_GRABBER */
   291 
   292   case VALHALLA_CFG_PARSER_KEYWORD:
   293     if (p1)
   294       vh_parser_bl_keyword_add (handle->parser, p1);
   295     break;
   296 
   297   case VALHALLA_CFG_SCANNER_PATH:
   298     if (p1)
   299       vh_scanner_path_add (handle->scanner, p1, i);
   300     break;
   301 
   302   case VALHALLA_CFG_SCANNER_SUFFIX:
   303     if (p1)
   304       vh_scanner_suffix_add (handle->scanner, p1);
   305     break;
   306 
   307   default:
   308     vh_log (VALHALLA_MSG_WARNING,
   309             "%s: unsupported option %#x", __FUNCTION__, conf);
   310     res = -1;
   311     break;
   312   }
   313 
   314   return res;
   315 }
   316 
   317 void
   318 valhalla_wait (valhalla_t *handle)
   319 {
   320   const int f = STOP_FLAG_REQUEST | STOP_FLAG_WAIT;
   321 
   322   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   323 
   324   if (!handle || handle->noscan)
   325     return;
   326 
   327   vh_scanner_wait (handle->scanner);
   328 
   329   vh_ondemand_stop (handle->ondemand, f);
   330   vh_dbmanager_wait (handle->dbmanager);
   331   vh_dispatcher_stop (handle->dispatcher, f);
   332   vh_parser_stop (handle->parser, f);
   333 #ifdef USE_GRABBER
   334   vh_grabber_stop (handle->grabber, f);
   335   vh_downloader_stop (handle->downloader, f);
   336 #endif /* USE_GRABBER */
   337   vh_event_handler_stop (handle->event_handler, f);
   338 
   339   handle->fstop = 1;
   340 }
   341 
   342 static void
   343 valhalla_force_stop (valhalla_t *handle)
   344 {
   345   unsigned int i;
   346 
   347   vh_log (VALHALLA_MSG_WARNING,
   348           "%s: This can take a time, please be patient", __FUNCTION__);
   349 
   350   for (i = 0; i < 2; i++)
   351   {
   352     int f = !i ? STOP_FLAG_REQUEST : STOP_FLAG_WAIT;
   353 
   354     vh_ondemand_stop (handle->ondemand, f);
   355     if (!handle->noscan)
   356       vh_scanner_stop (handle->scanner, f);
   357     vh_dbmanager_stop (handle->dbmanager, f);
   358     vh_dispatcher_stop (handle->dispatcher, f);
   359     vh_parser_stop (handle->parser, f);
   360 #ifdef USE_GRABBER
   361     vh_grabber_stop (handle->grabber, f);
   362     vh_downloader_stop (handle->downloader, f);
   363 #endif /* USE_GRABBER */
   364     vh_event_handler_stop (handle->event_handler, f);
   365   }
   366 
   367   valhalla_mrproper (handle);
   368 
   369   handle->fstop = 1;
   370 }
   371 
   372 void
   373 valhalla_uninit (valhalla_t *handle)
   374 {
   375   int preinit;
   376 
   377   vh_log (VALHALLA_MSG_VERBOSE, "%s: begin", __FUNCTION__);
   378 
   379   if (!handle)
   380     return;
   381 
   382   pthread_mutex_lock (&g_preinit_mutex);
   383   preinit = --g_preinit;
   384   pthread_mutex_unlock (&g_preinit_mutex);
   385 
   386   if (!handle->fstop)
   387     valhalla_force_stop (handle);
   388 
   389   /* dump all statistics */
   390   vh_stats_dump (handle->stats, NULL);
   391   vh_stats_debug_dump (handle->stats);
   392 
   393   vh_ondemand_uninit (handle->ondemand);
   394   vh_scanner_uninit (handle->scanner);
   395   vh_dbmanager_uninit (handle->dbmanager);
   396   vh_dispatcher_uninit (handle->dispatcher);
   397   vh_parser_uninit (handle->parser);
   398 #ifdef USE_GRABBER
   399   vh_grabber_uninit (handle->grabber);
   400   vh_downloader_uninit (handle->downloader);
   401 #endif /* USE_GRABBER */
   402   vh_event_handler_uninit (handle->event_handler);
   403 
   404 #if USE_GRABBER
   405   vh_url_global_uninit ();
   406 #endif /* USE_GRABBER */
   407 
   408 #ifdef USE_LAVC
   409   if (!preinit)
   410     av_lockmgr_register (NULL);
   411 #endif /* USE_LAVC */
   412 
   413   vh_stats_free (handle->stats);
   414 
   415   vh_log (VALHALLA_MSG_VERBOSE, "%s: end", __FUNCTION__);
   416 
   417   free (handle);
   418 }
   419 
   420 int
   421 valhalla_run (valhalla_t *handle, int loop, uint16_t timeout, int priority)
   422 {
   423   int res;
   424 
   425   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   426 
   427   if (!handle)
   428     return VALHALLA_ERROR_HANDLER;
   429 
   430   if (handle->run)
   431     return VALHALLA_ERROR_DEAD;
   432 
   433   handle->run = 1;
   434 
   435   if (handle->event_handler)
   436   {
   437     res = vh_event_handler_run (handle->event_handler, priority);
   438     if (res)
   439       return VALHALLA_ERROR_THREAD;
   440   }
   441 
   442   res = vh_scanner_run (handle->scanner, loop, timeout, priority);
   443   if (res)
   444   {
   445     if (res == SCANNER_ERROR_PATH)
   446     {
   447       handle->noscan = 1;
   448       vh_log (VALHALLA_MSG_INFO , "no path defined, scanner disabled");
   449     }
   450     else
   451       return VALHALLA_ERROR_THREAD;
   452   }
   453 
   454   res = vh_dbmanager_run (handle->dbmanager, priority);
   455   if (res)
   456     return VALHALLA_ERROR_THREAD;
   457 
   458   res = vh_dispatcher_run (handle->dispatcher, priority);
   459   if (res)
   460     return VALHALLA_ERROR_THREAD;
   461 
   462   res = vh_parser_run (handle->parser, priority);
   463   if (res)
   464     return VALHALLA_ERROR_THREAD;
   465 
   466 #ifdef USE_GRABBER
   467   res = vh_grabber_run (handle->grabber, priority);
   468   if (res)
   469     return VALHALLA_ERROR_THREAD;
   470 
   471   res = vh_downloader_run (handle->downloader, priority);
   472   if (res)
   473     return VALHALLA_ERROR_THREAD;
   474 #endif /* USE_GRABBER */
   475 
   476   res = vh_ondemand_run (handle->ondemand, priority);
   477   if (res)
   478     return VALHALLA_ERROR_THREAD;
   479 
   480   return VALHALLA_SUCCESS;
   481 }
   482 
   483 const char *
   484 valhalla_metadata_group_str (valhalla_meta_grp_t group)
   485 {
   486   return vh_metadata_group_str (group);
   487 }
   488 
   489 const char *
   490 valhalla_grabber_next (valhalla_t *handle, const char *id)
   491 {
   492   vh_log (VALHALLA_MSG_VERBOSE, "%s : %s", __FUNCTION__, id ? id : "");
   493 
   494   if (!handle)
   495     return NULL;
   496 
   497 #ifdef USE_GRABBER
   498   return vh_grabber_next (handle->grabber, id);
   499 #else
   500   vh_log (VALHALLA_MSG_WARNING,
   501           "This function is usable only with grabbing support!");
   502   return NULL;
   503 #endif /* USE_GRABBER */
   504 }
   505 
   506 valhalla_metadata_pl_t
   507 valhalla_grabber_priority_read (valhalla_t *handle,
   508                                 const char *id, const char **meta)
   509 {
   510   vh_log (VALHALLA_MSG_VERBOSE,
   511           "%s : %s/%s", __FUNCTION__, id ? id : "", meta && *meta ? *meta : "");
   512 
   513   if (!handle)
   514     return 0;
   515 
   516 #ifdef USE_GRABBER
   517   return vh_grabber_priority_read (handle->grabber, id, meta);
   518 #else
   519   vh_log (VALHALLA_MSG_WARNING,
   520           "This function is usable only with grabbing support!");
   521   return 0;
   522 #endif /* USE_GRABBER */
   523 }
   524 
   525 const char *
   526 valhalla_stats_group_next (valhalla_t *handle, const char *id)
   527 {
   528   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   529 
   530   if (!handle)
   531     return NULL;
   532 
   533   return vh_stats_group_next (handle->stats, id);
   534 }
   535 
   536 uint64_t
   537 valhalla_stats_read_next (valhalla_t *handle, const char *id,
   538                           valhalla_stats_type_t type, const char **item)
   539 {
   540   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   541 
   542   if (!handle)
   543     return 0;
   544 
   545   return vh_stats_read_next (handle->stats, id, type, item);
   546 }
   547 
   548 void
   549 valhalla_verbosity (valhalla_verb_t level)
   550 {
   551   vh_log_verb (level);
   552 }
   553 
   554 #ifdef USE_LAVC
   555 static int
   556 valhalla_avlock (void **mutex, enum AVLockOp op)
   557 {
   558   switch (op)
   559   {
   560   case AV_LOCK_CREATE:
   561     *mutex = malloc (sizeof (pthread_mutex_t));
   562     if (!*mutex)
   563       return 1;
   564     return !!pthread_mutex_init (*mutex, NULL);
   565 
   566   case AV_LOCK_OBTAIN:
   567     return !!pthread_mutex_lock (*mutex);
   568 
   569   case AV_LOCK_RELEASE:
   570     return !!pthread_mutex_unlock (*mutex);
   571 
   572   case AV_LOCK_DESTROY:
   573     pthread_mutex_destroy (*mutex);
   574     free (*mutex);
   575     return 0;
   576 
   577   default:
   578     return 1;
   579   }
   580 }
   581 #endif /* USE_LAVC */
   582 
   583 valhalla_t *
   584 valhalla_init (const char *db, valhalla_init_param_t *param)
   585 {
   586   int preinit;
   587   valhalla_t *handle;
   588   valhalla_init_param_t p;
   589   const valhalla_init_param_t *pp = &p;
   590 
   591   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   592 
   593   pthread_mutex_lock (&g_preinit_mutex);
   594   preinit = g_preinit;
   595   pthread_mutex_unlock (&g_preinit_mutex);
   596 
   597   if (!preinit && vh_osdep_init ())
   598     return NULL;
   599 
   600   if (!db)
   601     return NULL;
   602 
   603   if (param)
   604     pp = param;
   605   else
   606     memset (&p, 0, sizeof (p));
   607 
   608   handle = calloc (1, sizeof (valhalla_t));
   609   if (!handle)
   610     return NULL;
   611 
   612 #ifdef USE_GRABBER
   613   vh_url_global_init ();
   614 #endif /* USE_GRABBER */
   615 
   616   handle->stats = vh_stats_new ();
   617   if (!handle->stats)
   618     goto err;
   619 
   620   if (pp->od_cb || pp->gl_cb || pp->md_cb)
   621   {
   622     event_handler_cb_t cb;
   623 
   624     cb.od_cb = pp->od_cb;
   625     cb.gl_cb = pp->gl_cb;
   626     cb.md_cb = pp->md_cb;
   627     cb.od_data = pp->od_data;
   628     cb.gl_data = pp->gl_data;
   629     cb.md_data = pp->md_data;
   630 
   631     handle->event_handler = vh_event_handler_init (handle, &cb);
   632     if (!handle->event_handler)
   633       goto err;
   634   }
   635 
   636   handle->dispatcher = vh_dispatcher_init (handle);
   637   if (!handle->dispatcher)
   638     goto err;
   639 
   640   handle->parser = vh_parser_init (handle, pp->parser_nb, pp->decrapifier);
   641   if (!handle->parser)
   642     goto err;
   643 
   644 #ifdef USE_GRABBER
   645   handle->grabber = vh_grabber_init (handle, pp->grabber_nb);
   646   if (!handle->grabber)
   647     goto err;
   648 
   649   handle->downloader = vh_downloader_init (handle);
   650   if (!handle->downloader)
   651     goto err;
   652 #endif /* USE_GRABBER */
   653 
   654   handle->scanner = vh_scanner_init (handle);
   655   if (!handle->scanner)
   656     goto err;
   657 
   658   handle->dbmanager = vh_dbmanager_init (handle, db, pp->commit_int);
   659   if (!handle->dbmanager)
   660     goto err;
   661 
   662   handle->ondemand = vh_ondemand_init (handle);
   663   if (!handle->ondemand)
   664     goto err;
   665 
   666   if (!preinit)
   667   {
   668 #ifdef USE_LAVC
   669     if (av_lockmgr_register (valhalla_avlock))
   670       goto err;
   671 #endif /* USE_LAVC */
   672     av_log_set_level (AV_LOG_FATAL);
   673     av_register_all ();
   674   }
   675 
   676   pthread_mutex_lock (&g_preinit_mutex);
   677   g_preinit++;
   678   pthread_mutex_unlock (&g_preinit_mutex);
   679 
   680   return handle;
   681 
   682  err:
   683   valhalla_uninit (handle);
   684   return NULL;
   685 }
   686 
   687 void
   688 valhalla_scanner_wakeup (valhalla_t *handle)
   689 {
   690   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   691 
   692   if (!handle)
   693     return;
   694 
   695   vh_scanner_wakeup (handle->scanner);
   696 }
   697 
   698 void
   699 valhalla_ondemand (valhalla_t *handle, const char *file)
   700 {
   701   char *odfile;
   702 
   703   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   704 
   705   if (!handle || !file)
   706     return;
   707 
   708   odfile = strdup (file);
   709   if (!odfile)
   710     return;
   711 
   712   vh_ondemand_action_send (handle->ondemand, FIFO_QUEUE_PRIORITY_HIGH,
   713                            ACTION_OD_ENGAGE, odfile);
   714 }
   715 
   716 /******************************************************************************/
   717 /*                                                                            */
   718 /*                         Public Database Selections                         */
   719 /*                                                                            */
   720 /******************************************************************************/
   721 
   722 valhalla_db_stmt_t *
   723 valhalla_db_metalist_get (valhalla_t *handle, valhalla_db_item_t *search,
   724                           valhalla_file_type_t filetype,
   725                           valhalla_db_restrict_t *restriction)
   726 {
   727   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   728 
   729   if (!handle || !search)
   730     return NULL;
   731 
   732   return vh_dbmanager_db_metalist_get (handle->dbmanager,
   733                                        search, filetype, restriction);
   734 }
   735 
   736 const valhalla_db_metares_t *
   737 valhalla_db_metalist_read (valhalla_t *handle, valhalla_db_stmt_t *vhstmt)
   738 {
   739   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   740 
   741   if (!handle || !vhstmt)
   742     return NULL;
   743 
   744   return vh_dbmanager_db_metalist_read (handle->dbmanager, vhstmt);
   745 }
   746 
   747 valhalla_db_stmt_t *
   748 valhalla_db_filelist_get (valhalla_t *handle, valhalla_file_type_t filetype,
   749                           valhalla_db_restrict_t *restriction)
   750 {
   751   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   752 
   753   if (!handle)
   754     return NULL;
   755 
   756   return
   757     vh_dbmanager_db_filelist_get (handle->dbmanager, filetype, restriction);
   758 }
   759 
   760 const valhalla_db_fileres_t *
   761 valhalla_db_filelist_read (valhalla_t *handle, valhalla_db_stmt_t *vhstmt)
   762 {
   763   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   764 
   765   if (!handle || !vhstmt)
   766     return NULL;
   767 
   768   return vh_dbmanager_db_filelist_read (handle->dbmanager, vhstmt);
   769 }
   770 
   771 valhalla_db_stmt_t *
   772 valhalla_db_file_get (valhalla_t *handle, int64_t id, const char *path,
   773                       valhalla_db_restrict_t *restriction)
   774 {
   775   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   776 
   777   if (!handle)
   778     return NULL;
   779 
   780   return vh_dbmanager_db_file_get (handle->dbmanager, id, path, restriction);
   781 }
   782 
   783 const valhalla_db_metares_t *
   784 valhalla_db_file_read (valhalla_t *handle, valhalla_db_stmt_t *vhstmt)
   785 {
   786   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   787 
   788   if (!handle || !vhstmt)
   789     return NULL;
   790 
   791   return vh_dbmanager_db_file_read (handle->dbmanager, vhstmt);
   792 }
   793 
   794 /******************************************************************************/
   795 /*                                                                            */
   796 /*                  For Public Insertions/Updates/Deletions                   */
   797 /*                                                                            */
   798 /******************************************************************************/
   799 
   800 int
   801 valhalla_db_metadata_insert (valhalla_t *handle, const char *path,
   802                              const char *meta, const char *data,
   803                              valhalla_meta_grp_t group)
   804 {
   805   dbmanager_extmd_t *extmd;
   806 
   807   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   808 
   809   if (!handle || !path || !meta || !data)
   810     return -1;
   811 
   812   extmd = calloc (1, sizeof (dbmanager_extmd_t));
   813   if (!extmd)
   814     return -1;
   815 
   816   extmd->path  = strdup (path);
   817   extmd->meta  = strdup (meta);
   818   extmd->data  = strdup (data);
   819   extmd->group = group;
   820 
   821   vh_dbmanager_action_send (handle->dbmanager, FIFO_QUEUE_PRIORITY_HIGH,
   822                             ACTION_DB_EXT_INSERT, extmd);
   823   return 0;
   824 }
   825 
   826 int
   827 valhalla_db_metadata_update (valhalla_t *handle, const char *path,
   828                              const char *meta, const char *data,
   829                              const char *ndata)
   830 {
   831   dbmanager_extmd_t *extmd;
   832 
   833   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   834 
   835   if (!handle || !path || !meta || !data || !ndata)
   836     return -1;
   837 
   838   extmd = calloc (1, sizeof (dbmanager_extmd_t));
   839   if (!extmd)
   840     return -1;
   841 
   842   extmd->path  = strdup (path);
   843   extmd->meta  = strdup (meta);
   844   extmd->data  = strdup (data);
   845   extmd->ndata = strdup (ndata);
   846 
   847   vh_dbmanager_action_send (handle->dbmanager, FIFO_QUEUE_PRIORITY_HIGH,
   848                             ACTION_DB_EXT_UPDATE, extmd);
   849   return 0;
   850 }
   851 
   852 int
   853 valhalla_db_metadata_delete (valhalla_t *handle, const char *path,
   854                              const char *meta, const char *data)
   855 {
   856   dbmanager_extmd_t *extmd;
   857 
   858   vh_log (VALHALLA_MSG_VERBOSE, __FUNCTION__);
   859 
   860   if (!handle || !path || !meta || !data)
   861     return -1;
   862 
   863   extmd = calloc (1, sizeof (dbmanager_extmd_t));
   864   if (!extmd)
   865     return -1;
   866 
   867   extmd->path  = strdup (path);
   868   extmd->meta  = strdup (meta);
   869   extmd->data  = strdup (data);
   870 
   871   vh_dbmanager_action_send (handle->dbmanager, FIFO_QUEUE_PRIORITY_HIGH,
   872                             ACTION_DB_EXT_DELETE, extmd);
   873   return 0;
   874 }