Piesek64
Piesek64

Reputation: 67

No instance for Database.SQLite.Simple.FromField.FromField Char

This code gives me an error:

67:    isFileInstalled f = do
68:                dbcon <- open "/var/lib/beaver/pkgs.db"
69:                res <- queryNamed dbcon "SELECT * FROM files WHERE path = :path" [":path" := ("/usr/bin/getpkg" :: String)]
70:                mapM_ putStrLn res
71:                -- when (null res) (return ())
72:                -- putStrLn ("File " ++ res ++ " is already installed and comes from " ++ res ++ ".") -- first res is `owner` and second is `path`
73:                close dbcon
74:                exit

I get this error:

No instance for (Database.SQLite.Simple.FromField.FromField Char)
     arising from a use of `queryNamed'    In a stmt of a 'do' block:
     res <- queryNamed
              dbcon
              "SELECT * FROM files WHERE path = :path"
              [":path" := ("/usr/bin/getpkg" :: String)]    In the expression:
     do { dbcon <- open "/var/lib/beaver/pkgs.db";
          res <- queryNamed
                   dbcon
                   "SELECT * FROM files WHERE path = :path"
                   [":path" := ("/usr/bin/getpkg" :: String)];
          mapM_ putStrLn res;
          close dbcon;
          .... }    In an equation for `isFileInstalled':
       isFileInstalled f
         = do { dbcon <- open "/var/lib/beaver/pkgs.db";
                res <- queryNamed
                         dbcon
                         "SELECT * FROM files WHERE path = :path"
                         [":path" := ("/usr/bin/getpkg" :: String)];
                mapM_ putStrLn res;

I didn't find anything in Google. If it's important, OverloadedStrings are enabled. Is there workaround (or way to fix it)?

Upvotes: 3

Views: 789

Answers (1)

Yuras
Yuras

Reputation: 13876

You are using res as a [String]:

mapM_ putStrLn res

It is equivalent to [[Char]]. But queryNamed returns a list of rows, so each row has type [Char]. There is an instance FromField a => FromRow [a], but there is no instance FromField Char. That is what the error messages says.

I never used sqlite-simple, but it is clear that each row contains a number of fields, so you are trying to fetch a row that contains a number of fields of type Char. That makes no sense. Depending on actual database scheme, each row should be e.g. a number of text field, then the res can have type [[String]]. In that case you should use it like the next:

mapM_ (mapM_ putStrLn) (res :: [[String]])

Upvotes: 2

Related Questions