2010-08-26 8 views
5

Ho appena iniziato un nuovo progetto e volevo utilizzare HaskellDB all'inizio. Ho creato un database con 2 colonne:Inserimento SQL parziale in haskelldb

create table sensor (
    service text, 
    name text 
); 

..found il modo di fare il macchinario HaskellDB base (ohhh..the documentazione) e voleva fare un inserto. Tuttavia, ho voluto fare un inserto parziale (ci si suppone siano più colonne), qualcosa come:

insert into sensor (service) values ('myservice'); 

Tradotto in HaskellDB:

transaction db $ insert db SE.sensor (SE.service <<- (Just $ senService sensor)) 

Ma ... che semplicemente non funziona . Inoltre, ciò che non funziona è se si specificano i nomi delle colonne in ordine diverso, il che non è esattamente conveniente. C'è un modo per inserire un inserto parziale in haskelldb?

I codici di errore che ottengo sono - quando ho appena inserito una colonna diversa (il 'nome') come il primo:

Couldn't match expected type `SEI.Service' 
     against inferred type `SEI.Name' 
    Expected type: SEI.Intsensor 
    Inferred type: Database.HaskellDB.HDBRec.RecCons 
        SEI.Name (Expr String) er 
When using functional dependencies to combine 
    Database.HaskellDB.Query.InsertRec 
    (Database.HaskellDB.HDBRec.RecCons f (e a) r) 
    (Database.HaskellDB.HDBRec.RecCons f (Expr a) er), 
etc.. 

E quando faccio il 'servizio' come il primo - e unico - campo, ottengo:

Couldn't match expected type `Database.HaskellDB.HDBRec.RecCons 
           SEI.Name 
           (Expr String) 
           (Database.HaskellDB.HDBRec.RecCons 
            SEI.Time 
            (Expr Int) 
            (Database.HaskellDB.HDBRec.RecCons 
             SEI.Intval (Expr Int) Database.HaskellDB.HDBRec.RecNil))' 
     against inferred type `Database.HaskellDB.HDBRec.RecNil' 

(ho un paio di altre colonne della tabella) Questo sembra veramente 'by design', purtroppo :(

+0

Sarebbe utile sapere quali errori si vedono e i tipi calcolati per alcune espressioni intermedie. –

risposta

4

Hai ragione, che doe s sembra intenzionale. I documenti mostrano che HaskellDB.Query insert ha un tipo di:

insert :: (ToPrimExprs r, ShowRecRow r, InsertRec r er) => Database -> Table er -> Record r -> IO() 

In particolare, la relazione InsertRec r er deve tenere. Questo è definito altrove dal programma di tipo ricorsivo:

InsertRec RecNil RecNil 
(InsertExpr e, InsertRec r er) => InsertRec (RecCons f (e a) r) (RecCons f (Expr a) er) 

La prima riga è il caso base. La seconda linea è un caso induttivo. Vuole davvero camminare su ogni elemento di er, sul tavolo. Non c'è cortocircuito e nessun supporto per il riordino. Ma nelle mie prove, ho visto questo lavoro, utilizzando _default:

insQ db = insert db test_tbl1 (c1 <<- (Just 5) # c2 << _default) 

Quindi, se volete un inserto parziali, si può sempre dire:

insC1 db x = insert db test_tbl1 (c1 <<- (Just x) # c2 << _default) 
insC2 db x = insert db test_tbl2 (c1 << _default # c2 <<- (Just x)) 

Mi rendo conto che questo non è tutto ciò che si stai cercando. Sembra che InsertRec possa essere riscritto nello stile di HList, per consentire una maggiore generalizzazione. Questo sarebbe un contributo eccellente.

Problemi correlati