<commit_before>{-# LANGUAGE OverloadedStrings
           , FlexibleContexts
           , TemplateHaskell
           , QuasiQuotes
           , DeriveGeneric
           , StandaloneDeriving
           , ScopedTypeVariables #-}

module DB where

import qualified GHC.Generics as GHC
import qualified Data.Text as Text
import Data.Aeson
import Database.PostgreSQL.Simple
import Database.PostgreSQL.Simple.FromField
import Database.PostgreSQL.Simple.ToField
import Database.PostgreSQL.Simple.SqlQQ

import API
import Types

--------------------------------------------
---- Types and instances for PostgreSQL ----
--------------------------------------------

deriving instance GHC.Generic ConnectInfo

instance ToJSON ConnectInfo
instance FromJSON ConnectInfo

type DatabaseConfig = ConnectInfo

type ClientID = Int

dbConnect :: DatabaseConfig -> IO Connection
dbConnect = connect

dbDisconnect :: Connection -> IO ()
dbDisconnect = close

dbSelectAllFiles :: Connection -> IO [OwnedSourceFile]
dbSelectAllFiles conn = do
  rows <- query_ conn [sql| select * from files |] ::
              IO [(Integer, ClientID, FilePath, Text.Text)]
  return $ map readRow rows
    where
      readRow (_, cid, path, contents) =
        OwnedSourceFile cid (SourceFile path contents)

dbInsertFile :: Connection -> ClientID -> SourceFile -> IO ()
dbInsertFile conn clientID (SourceFile path contents) =
  execute conn [sql|
    INSERT INTO files(clientID, filePath, fileContents) VALUES
      (?, ?, ?)
  |] (clientID, path, contents) >> return ()

dbUpdateFiles :: Connection -> ClientID -> [SourceFile] -> IO ()
dbUpdateFiles conn clientID files = do
  execute conn [sql|
    DELETE FROM files WHERE clientid = ?
  |] (Only clientID)
  mapM_ (dbInsertFile conn clientID) files

dbAddTeacher :: Connection -> Credential -> IO Int
dbAddTeacher conn (Credential uname pwd) = do
  teacher_id :: [Only Int] <- query conn [sql|
    INSERT INTO teachers (teacher_id, username, password)
      VALUES (DEFAULT,?,?) RETURNING teacher_id
  |] (uname, pwd)
  return . fromOnly . head $ teacher_id

dbLookupTeacher :: Connection -> Credential -> IO Bool<commit_msg>Fixed DB functions for CRUD operations of files.<commit_after>{-# LANGUAGE OverloadedStrings
           , FlexibleContexts
           , TemplateHaskell
           , QuasiQuotes
           , DeriveGeneric
           , StandaloneDeriving
           , ScopedTypeVariables #-}

module DB where

import qualified GHC.Generics as GHC
import qualified Data.Text as Text
import Data.Aeson
import Database.PostgreSQL.Simple
import Database.PostgreSQL.Simple.FromField
import Database.PostgreSQL.Simple.ToField
import Database.PostgreSQL.Simple.SqlQQ

import API
import Types

--------------------------------------------
---- Types and instances for PostgreSQL ----
--------------------------------------------

deriving instance GHC.Generic ConnectInfo

instance ToJSON ConnectInfo
instance FromJSON ConnectInfo

type DatabaseConfig = ConnectInfo

type StudentID = Int

dbConnect :: DatabaseConfig -> IO Connection
dbConnect = connect

dbDisconnect :: Connection -> IO ()
dbDisconnect = close

dbSelectAllFiles :: Connection -> IO [OwnedSourceFile]
dbSelectAllFiles conn = do
  rows <- query_ conn [sql| select * from files |] ::
              IO [(Integer, FilePath, Text.Text, StudentID)]
  return $ map readRow rows
    where
      readRow (_, path, contents, student_id) =
        OwnedSourceFile student_id (SourceFile path contents)

dbInsertFile :: Connection -> StudentID -> SourceFile -> IO ()
dbInsertFile conn student_id (SourceFile path contents) =
  execute conn [sql|
    INSERT INTO files(file_id, file_path, file_contents, student_id) VALUES
      (DEFAULT, ?, ?, ?)
  |] (path, contents, student_id) >> return ()

dbUpdateFiles :: Connection -> StudentID -> [SourceFile] -> IO ()
dbUpdateFiles conn student_id files = do
  execute conn [sql|
    DELETE FROM files WHERE student_id = ?
  |] (Only student_id)
  mapM_ (dbInsertFile conn student_id) files

dbAddTeacher :: Connection -> Credential -> IO Int
dbAddTeacher conn (Credential uname pwd) = do
  teacher_id :: [Only Int] <- query conn [sql|
    INSERT INTO teachers (teacher_id, username, password)
      VALUES (DEFAULT,?,?) RETURNING teacher_id
  |] (uname, pwd)
  return . fromOnly . head $ teacher_id

dbLookupTeacher :: Connection -> Credential -> IO Bool
{'fraction_non_alphanumeric': 0.12577319587628866, 'fraction_numerical': 0.0, 'mean_word_length': 3.0091827364554637, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6130314', 'n_tokens_mistral': 1233, 'n_tokens_neox': 1190, 'n_words': 384}