From: Jeremy S. <jer...@li...> - 2004-04-07 23:05:30
|
Here is a way to get last_insert_id() working for mysql. The nice thing about this solution is it can be used without modifying the library code at all. It is based, in part, on test/current_time.hs . First I defined a module LastInsertID.hs --> module LastInsertID where import Database.HaskellDB.HDBRec import Database.HaskellDB.HDBRecUtils import Database.HaskellDB.BoundedString import System.Time (CalendarTime) import Database.HaskellDB.Query (Expr, Table, Attr, baseTable) import Database.HaskellDB.DBSpec import Database.HaskellDB.FieldType --------------------------------------------------------------------------- -- Table --------------------------------------------------------------------------- lastinsertid :: Table ((HDBRecCons Last_insert_id (Expr Integer) HDBRecTail)) lastinsertid = baseTable "lastinsertid()" $ hdbMakeEntry Last_insert_id --------------------------------------------------------------------------- -- Fields --------------------------------------------------------------------------- --------------------------------------------------------------------------- -- Bug_id Field --------------------------------------------------------------------------- data Last_insert_id = Last_insert_id instance FieldTag Last_insert_id where fieldName _ = "lastInsertID" last_insert_id :: Attr Last_insert_id Integer last_insert_id = mkAttr Last_insert_id <-- Then in my Main.hs I imported LastInsertId and I defined: -- | similar to doInsert, except it returns LAST_INSERT_ID() doInsertLastID :: forall r. (ShowRecRow r, ToPrimExprs r) => Table r -> (HDBRecTail -> r) -> IO Integer doInsertLastID table record = mysqlConnect opts $ \db -> do insert db table record (r:_) <- dbQuery db lastInsertIDQ ((Rel 0 ["lastInsertID"]) :: Rel ((HDBRecCons Last_insert_id (Expr Integer) HDBRecTail))) return (Row r!last_insert_id) where lastInsertIDQ = Project [("lastInsertID", BinExpr (OpOther "last_insert_id()") (ConstExpr "") (ConstExpr ""))] Empty now I can do something like: filebug assigned_to short_desc product component = do i <- doInsertLastID B.bugs ( B.bug_id << sqlnull # B.groupset << constant 0 # B.assigned_to << constant assigned_to # B.bug_file_loc << constant Nothing # B.bug_severity << constant "normal" # B.bug_status << constant "NEW" # B.creation_ts << sqlnow # B.delta_ts << sqlnow # B.short_desc << constJust short_desc # B.op_sys << constant "other" # B.priority << constant "P1" # B.product << constant product # B.rep_platform << constJust "PC" # B.reporter << constant assigned_to # B.version << constant "Marlin" # B.component << constant component # B.resolution << constant "" # B.target_milestone << constant "---" # B.qa_contact << constant 0 # B.status_whiteboard << constant "" # B.votes << constant 0 # B.keywords << constant "" # B.lastdiffed << sqlnow # B.everconfirmed << constant 1 # B.reporter_accessible << constant 1 # B.cclist_accessible << constant 1 ) return i NOTE: I originally named the field 'last_insert_id' which worked fine under mysql 4.1.X but not under mysql 3.23.X. OTHER NOTE: yes, MySQL 4.1.X is required if you need sub-selects, but since I was just doing a bunch of inserts and simple selects, 3.23 works fine. FINAL NOTE: This is all a hack and should probably be hidden from the user more elegantly. Jeremy Shaw. |