Frage

ich ein Beispiel C-Funktion haben, dass ich auf eine Datenbank temp.sqlite anhängen möchten (es ist von einem O'Reilly-Buch, damit ich weiß, es funktioniert). Ich lese den Abschnitt im Buch und sqlite.org, aber sie übernehmen weg, dass ich weiß, wie und wo diese Sache mit den richtigen Einstellungen zu kompilieren. Ich bin auf beide Mac (mit XCode) oder Ubuntu.

Ich weiß genug C, um den Code zu verändern, zu tun, was ich will, aber ich habe keine Ahnung, was es zu tun ruft aus meiner Datenbank temp.sqlite.

Vielen Dank für Ihre Hilfe! Ich habe auf diese wurde am laufenden Band!

Update: Noch ein paar Stunden in und ich verschrottet habe zusammen genug Sachen aus aufgegeben Webseiten einen Compiler-Befehl zu erstellen und einen Fehler erzeugen:

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, hier wtavg.c, die direkt aus der O'Reilly-Website in meinem Buch vorgesehen ist:

/* 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;
}
War es hilfreich?

Lösung

Die benutzerdefinierte Funktion sollte als Shared Library-Datei kompiliert werden:

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

Das gemeinsam genutzte Bibliothek kann dann geladen werden, um eine SQLite-Anweisung:

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

Leider ist die Version von sqlite3 von Apple bereitgestellten nicht Laden gemeinsam genutzten Bibliotheken unterstützen. Sie können stattdessen SQLite von MacPorts verwenden. MacPorts Programme Verknüpfung mit SQLite sollte auch die Möglichkeit, Last auf diese Weise definierte Funktionen Benutzer haben.

Bei der Verwendung von SQLite in einem anderen Programm jedoch der Verlängerung Lademechanismus kann aus Sicherheitsgründen deaktiviert werden. In Python zum Beispiel haben Sie Anruf con.enable_load_extension(True) es zu aktivieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top