2024-12-20 00:52:27 +00:00
package database
2024-12-20 13:28:54 +00:00
import (
"database/sql"
"errors"
)
2024-12-20 00:52:27 +00:00
type DB struct {
Host string
User string
Password string
Name string
Port string
}
2024-12-20 13:28:54 +00:00
var (
database DB
)
2024-12-20 00:52:27 +00:00
2024-12-20 13:28:54 +00:00
func SetEnv ( env map [ string ] string ) * DB {
2024-12-20 00:52:27 +00:00
var db DB
db . Host = env [ "DB_HOST" ]
db . User = env [ "DB_USER" ]
db . Password = env [ "DB_PASSWORD" ]
db . Name = env [ "DB_NAME" ]
db . Port = env [ "DB_PORT" ]
database = db
2024-12-20 13:28:54 +00:00
checkDatabase ( )
return & db
}
func New ( ) ( * sql . DB , error ) {
conn , err := sql . Open ( "postgres" , connect ( ) )
if err != nil {
return nil , err
}
return conn , nil
}
func connect ( ) string {
return "user=" + database . User + " password=" + database . Password + " dbname=" + database . Name + " sslmode=disable"
}
func checkDatabase ( ) {
conn , err := sql . Open ( "postgres" , "user=" + database . User + " password=" + database . Password + " dbname=postgres sslmode=disable" )
if err != nil {
panic ( err )
}
defer conn . Close ( )
err = conn . QueryRow ( "SELECT datname FROM pg_database WHERE datname = $1" , database . Name ) . Scan ( & database . Name )
if err != nil {
if err == sql . ErrNoRows {
createDatabase ( )
} else {
panic ( err )
}
}
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func createDatabase ( ) {
conn , err := sql . Open ( "postgres" , "user=" + database . User + " password=" + database . Password + " dbname=postgres sslmode=disable" )
if err != nil {
panic ( err )
}
defer conn . Close ( )
_ , err = conn . Exec ( "CREATE DATABASE " + database . Name )
if err != nil {
panic ( err )
}
}
func checkTables ( ) {
2024-12-20 00:52:27 +00:00
}
func createTables ( ) {
}
func updateTables ( ) {
}
2024-12-20 13:28:54 +00:00
func existAccount ( database * sql . DB , id int ) ( bool , error ) {
err := database . QueryRow ( "SELECT id FROM accounts WHERE id = $1" , id ) . Scan ( & id )
if err != nil {
if err != sql . ErrNoRows {
return false , err
}
return false , nil
}
return true , nil
}
2024-12-20 00:52:27 +00:00
2024-12-20 13:28:54 +00:00
func NewAccount ( database * sql . DB , account Account ) error {
exists , err := existAccount ( database , int ( account . ID ) )
if err != nil {
return err
}
if exists {
return errors . New ( "account already exists" )
}
_ , err = database . Exec ( "INSERT INTO accounts (id, name, kind) VALUES ($1, $2, $3)" , account . ID , account . Name , account . Kind )
if err != nil {
return err
}
return nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func UpdateAccount ( database * sql . DB , account Account ) error {
_ , err := database . Exec ( "UPDATE accounts SET name = $1, kind = $2 WHERE id = $3" , account . Name , account . Kind , account . ID )
if err != nil {
return err
}
return nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func DeleteAccount ( database * sql . DB , id int ) error {
_ , err := database . Exec ( "DELETE FROM accounts WHERE id = $1" , id )
if err != nil {
return err
}
return nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func GetAccount ( database * sql . DB , id int ) ( Account , error ) {
var account Account
err := database . QueryRow ( "SELECT * FROM accounts WHERE id = $1" , id ) . Scan ( & account . ID , & account . Name , & account . Kind )
if err != nil {
return account , err
}
return account , nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func NewTransaction ( database * sql . DB , transaction Transaction ) error {
_ , err := database . Exec ( "INSERT INTO transactions (amount, debit, offset_account, account, time, description) VALUES ($1, $2, $3, $4, $5, $6)" , transaction . Amount , transaction . Debit , transaction . OffsetAccount , transaction . Account , transaction . Time , transaction . Description )
if err != nil {
return err
}
return nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func UpdateTransaction ( database * sql . DB , transaction Transaction ) error {
_ , err := database . Exec ( "UPDATE transactions SET amount = $1, debit = $2, offset_account = $3, account = $4, time = $5, description = $6 WHERE id = $7" , transaction . Amount , transaction . Debit , transaction . OffsetAccount , transaction . Account , transaction . Time , transaction . Description , transaction . ID )
if err != nil {
return err
}
return nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func DeleteTransaction ( database * sql . DB , id int ) error {
_ , err := database . Exec ( "DELETE FROM transactions WHERE id = $1" , id )
if err != nil {
return err
}
return nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func GetTransaction ( database * sql . DB , id int ) ( Transaction , error ) {
var transaction Transaction
err := database . QueryRow ( "SELECT * FROM transactions WHERE id = $1" , id ) . Scan ( & transaction . ID , & transaction . Amount , & transaction . Debit , & transaction . OffsetAccount , & transaction . Account , & transaction . Time , & transaction . Description )
if err != nil {
return transaction , err
}
return transaction , nil
}
func GetTransactions ( database * sql . DB , account int , year int , month int ) ( [ ] Transaction , error ) {
var transactions [ ] Transaction
var row * sql . Rows
var err error
if year == 0 {
return nil , errors . New ( "year is required" )
}
2024-12-20 14:19:33 +00:00
// TODO: Extract is probably not used right
2024-12-20 13:28:54 +00:00
if month == 0 {
row , err = database . Query ( "SELECT * FROM transactions WHERE account = $1 AND EXTRACT(YEAR FROM time) = $2" , account , year )
} else {
row , err = database . Query ( "SELECT * FROM transactions WHERE account = $1 AND EXTRACT(YEAR FROM time) = $2 AND EXTRACT(MONTH FROM time) = $3" , account , year , month )
}
if err != nil {
return nil , err
}
defer row . Close ( )
for row . Next ( ) {
var transaction Transaction
err := row . Scan ( & transaction . ID , & transaction . Amount , & transaction . Debit , & transaction . OffsetAccount , & transaction . Account , & transaction . Time , & transaction . Description )
if err != nil {
return nil , err
}
transactions = append ( transactions , transaction )
}
return transactions , nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func NewUser ( database * sql . DB , user User ) error {
_ , err := database . Exec ( "INSERT INTO users (name, password) VALUES ($1, $2)" , user . Name , user . Password )
if err != nil {
return err
}
return nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func UpdateUser ( database * sql . DB , user User ) error {
_ , err := database . Exec ( "UPDATE users SET name = $1, password = $2 WHERE id = $3" , user . Name , user . Password , user . ID )
if err != nil {
return err
}
return nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 13:28:54 +00:00
func DeleteUser ( database * sql . DB , id int ) error {
_ , err := database . Exec ( "DELETE FROM users WHERE id = $1" , id )
if err != nil {
return err
}
return nil
}
2024-12-20 00:52:27 +00:00
2024-12-20 13:28:54 +00:00
func GetUser ( database * sql . DB , id int ) ( User , error ) {
var user User
err := database . QueryRow ( "SELECT * FROM users WHERE id = $1" , id ) . Scan ( & user . ID , & user . Name , & user . Password )
if err != nil {
return user , err
}
return user , nil
2024-12-20 00:52:27 +00:00
}
2024-12-20 14:19:33 +00:00
func GetUserByName ( database * sql . DB , name string ) ( User , error ) {
var user User
err := database . QueryRow ( "SELECT * FROM users WHERE name = $1" , name ) . Scan ( & user . ID , & user . Name , & user . Password )
if err != nil {
return user , err
}
return user , nil
}
2024-12-20 13:28:54 +00:00
func AuthenicateUser ( database * sql . DB , name string , password string ) ( User , error ) {
var user User
err := database . QueryRow ( "SELECT * FROM users WHERE name = $1 AND password = $2" , name , password ) . Scan ( & user . ID , & user . Name , & user . Password )
if err != nil {
return user , err
}
return user , nil
2024-12-20 00:52:27 +00:00
}