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