Question

J'ai une fonction par exemple C que je voudrais joindre à une base de données temp.sqlite (il est d'un livre O'Reilly, donc je sais que cela fonctionne). J'ai lu la section dans le livre et sqlite.org, mais ils tiennent pour acquis que je sais comment et où compiler cette chose avec les paramètres appropriés. Je suis sous Mac (avec XCode) ou Ubuntu.

Je sais assez C pour modifier le code pour faire ce que je veux, mais je ne sais pas quoi faire appeler de ma base de données temp.sqlite.

Merci pour votre aide! J'ai barattage à ce sujet!

Mise à jour: A quelques heures et je l'ai mis au rebut des choses ensemble assez de pages Web pour créer une abandonnés commande compiler et générer une erreur:

richard$ gcc -o wtavg wtavg.c -Wall -W -O2 -L/usr/local/lib -lsqlite3
wtavg.c: In function ‘wtavg_init’:
wtavg.c:63: warning: unused parameter ‘error’
Undefined symbols:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

FWIW, le wtavg.c d'ici, qui est directement à partir du site O'Reilly fourni dans mon livre:

/* wtavg.c */

#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1;

#include <stdlib.h>




typedef struct wt_avg_state_s {
   double   total_data;  /* sum of (data * weight) values */
   double   total_wt;    /* sum of weight values */
} wt_avg_state;


static void wt_avg_step( sqlite3_context *ctx, int num_values, sqlite3_value **values )
{
    double         row_wt = 1.0;
    int            type;
    wt_avg_state   *st = (wt_avg_state*)sqlite3_aggregate_context( ctx,
                                               sizeof( wt_avg_state ) );
    if ( st == NULL ) {
        sqlite3_result_error_nomem( ctx );
        return;
    }

    /* Extract weight, if we have a weight and it looks like a number */
    if ( num_values == 2 ) {
        type = sqlite3_value_numeric_type( values[1] );
        if ( ( type == SQLITE_FLOAT )||( type == SQLITE_INTEGER ) ) {
            row_wt = sqlite3_value_double( values[1] );
        }
    }

    /* Extract data, if we were given something that looks like a number. */
    type = sqlite3_value_numeric_type( values[0] );
    if ( ( type == SQLITE_FLOAT )||( type == SQLITE_INTEGER ) ) {
        st->total_data += row_wt * sqlite3_value_double( values[0] );
        st->total_wt   += row_wt;
    }
}


static void wt_avg_final( sqlite3_context *ctx )
{
    double         result = 0.0;
    wt_avg_state   *st = (wt_avg_state*)sqlite3_aggregate_context( ctx,
                                               sizeof( wt_avg_state ) );
    if ( st == NULL ) {
        sqlite3_result_error_nomem( ctx );
        return;
    }

    if ( st->total_wt != 0.0 ) {
        result = st->total_data / st->total_wt;
    }
    sqlite3_result_double( ctx, result );
}


int wtavg_init( sqlite3 *db, char **error, const sqlite3_api_routines *api )
{
    SQLITE_EXTENSION_INIT2(api);

    sqlite3_create_function( db, "wtavg", 1, SQLITE_UTF8,
            NULL, NULL, wt_avg_step, wt_avg_final );
    sqlite3_create_function( db, "wtavg", 2, SQLITE_UTF8,
            NULL, NULL, wt_avg_step, wt_avg_final );

    return SQLITE_OK;
}
Était-ce utile?

La solution

doit être compilé La fonction définie par l'utilisateur sous forme de fichier bibliothèque partagée:

gcc -shared -fPIC -o wtavg.so wtavg.c -lsqlite3

Cette bibliothèque partagée peut alors être chargé en utilisant une instruction SQLite:

SELECT load_extension('/path/to/wt_avg.so', 'wtavg_init');

Malheureusement, la version de sqlite3 fourni par Apple ne prend pas en charge le chargement des bibliothèques partagées. Vous pouvez utiliser SQLite de MacPorts à la place. programmes MacPorts reliant contre sqlite devraient également avoir la capacité de l'utilisateur charge des fonctions définies ainsi.

Lorsque vous utilisez SQLite dans un autre programme mais le mécanisme de chargement d'extension peut être désactivé pour des raisons de sécurité. En Python par exemple, vous devez appeler con.enable_load_extension(True) pour l'activer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top