Как выбрать из упорядочения таблиц по первичному ключу

У меня есть эта постоянная схема SQLite:

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Entry
  class EntryClass
|]

Это соответствует следующему оператору CREATE TABLE:

CREATE TABLE "entry"
  ( "id" INTEGER PRIMARY KEY AUTOINCREMENT
  , "class" INTEGER NOT NULL);"

Я вручную добавил ключевое слово AUTOINCREMENT, чтобы быть уверенным, что идентификаторы всегда монотонно возрастают. Теперь я хочу выбрать самую старую запись из базы данных — ту, у которой самый низкий идентификатор.

Если бы я писал SQL, я бы сказал что-то вроде этого:

SELECT id, class FROM entry ORDER BY id ASC LIMIT 1

Но у меня проблемы с переводом этого запроса на постоянный. Это должно выглядеть примерно так

nextEntry <- selectFirst [] [Asc EntryId, LimitTo 1]

но это дает мне синтаксическую ошибку, жалующуюся на то, что нет конструктора данных EntryId. Действительно, EntryId является синонимом типа Database.Persist.Class.PersistEntity.Key Entry, поэтому его нельзя использовать в конструкторе данных Asc, который имеет тип forall typ . Asc (EntityField record typ).

Итак, вопрос в том, как я могу сделать постоянный порядок результатов моего запроса по первичному ключу таблицы?


person Anton    schedule 24.11.2014    source источник


Ответы (1)


Это действительно должно работать; EntryId является одновременно типом и конструктором данных. Например, следующий код (только что измененный из синопсиса персистентной главы книги Йесод) компилируется нормально:

{-# LANGUAGE EmptyDataDecls             #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE GADTs                      #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE QuasiQuotes                #-}
{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE TypeFamilies               #-}
import Control.Monad.IO.Class  (liftIO)
import Database.Persist
import Database.Persist.Sqlite
import Database.Persist.TH

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
    name String
    age Int Maybe
    deriving Show
|]

main :: IO ()
main = runSqlite ":memory:" $ do
    runMigration migrateAll

    johnId <- insert $ Person "John Doe" $ Just 35
    janeId <- insert $ Person "Jane Doe" Nothing

    selectList [] [Asc PersonId] >>= liftIO . mapM_ print
person Michael Snoyman    schedule 24.11.2014
comment
Упс, кажется, я забыл экспортировать конструктор данных EntryId из моего модуля сущностей. После правильного экспорта оказалось, что мой код компилируется хорошо. Я также был несколько введен в заблуждение сгенерированными шаблонными соединениями haskell и не заметил, что на самом деле существует конструктор данных EntryId, который видит только синоним типа. Простите за это :( - person Anton; 24.11.2014