2011-12-06 10 views
6

Provo ad abilitare chiavi esterne utilizzando la libreria haskell HDBC-sqlite3. Questa libreria utilizza un piccolo aiutante c - funzioneTasti esterni Sqlite

int sqlite3_open2(const char *filename, finalizeonce **ppo) 

che richiede a sua volta una sqlite3_open. Nel sqlite documentation ho trovato una bella funzione sqlite3_db_config che dovrebbe abilitare le chiavi esterne. Per provarlo ho aggiunto subito 2 linee in sqlite3_open2 (i due ultimi della lista):

int sqlite3_open2(const char *filename, finalizeonce **ppo) { 
    sqlite3 *ppDb; 
    finalizeonce *newobj; 
    int res, *resFK, resFK1; 

    fprintf(stderr, "DB pointer: %d\n", ppDb); 

    res = sqlite3_open(filename, &ppDb); 

    resFK1 = sqlite3_db_config(ppDb, 1002, 1, resFK);      
    fprintf(stderr, "\nForeign Keys: ON/OFF:%d ERR:%d\n", resFK, resFK1); 

    ... 

La mia sorpresa è stato il risultato: Foreign Keys: ON/OFF:0 ERR:1.

Qualcuno potrebbe darmi un suggerimento su cosa sto sbagliando o quale sarebbe il modo corretto di abilitare le chiavi esterne?

risposta

6

Secondo il docs:

Supponendo che la libreria viene compilata con i vincoli di chiave esterna abilitata, si deve ancora essere abilitato mediante l'applicazione in fase di esecuzione, utilizzando il comando PRAGMA FOREIGN_KEYS. Ad esempio:

sqlite> PRAGMA foreign_keys = ON;

I vincoli di chiave esterna sono disabilitati per impostazione predefinita (per compatibilità con backward ), quindi devono essere abilitati separatamente per ogni connessione di database separatamente.

Così, dopo la vostra sqlite3_open(), probabilmente si desidera aggiungere il seguente:

sqlite3_exec(ppDb, "PRAGMA foreign_keys = ON;", 0, 0, 0); 
+0

la soluzione funziona. Mi hai aperto gli occhi per quanto riguarda come risolvere il mio problema a livello di Haskell. Una volta finito, lo posterò qui. – bartoszw

3

ho avuto difficoltà con abilitazione chiavi esterne utilizzando HDBC-sqlite3 API perché citato PRAGMA tenuto ad essere invocate al di là delle transazioni e la libreria apre in background una nuova transazione dopo che la connessione viene stabilita e dopo ogni commit. Ancora la soluzione è stata semplice:

main = do 
    conn <- connectSqlite3 "test.db" 
    runRaw conn "COMMIT; PRAGMA foreign_keys = ON; BEGIN TRANSACTION"