set and get now work trough endpoint api

This commit is contained in:
zipfriis
2026-03-25 17:44:04 +01:00
parent b9f462f5be
commit e056d8a37e
7 changed files with 82 additions and 18 deletions

Binary file not shown.

BIN
app.db

Binary file not shown.

View File

@@ -19,3 +19,15 @@ func GetCurrencyByID(db *sql.DB, ID int) (model.Currency, error) {
} }
return c, nil return c, nil
} }
func GetCurrencyByCode(db *sql.DB, Code string) (model.Currency, error) {
var c model.Currency
err := db.QueryRow(
`SELECT id, code, name, FROM currencies WHERE code = ?`,
Code,
).Scan(&c.ID, &c.Code, &c.Name)
if err == sql.ErrNoRows {
return c, fmt.Errorf("company %d not found", Code)
}
return c, nil
}

View File

@@ -23,17 +23,17 @@ func InitDB(db *sql.DB) {
shares INTEGER NOT NULL, shares INTEGER NOT NULL,
product INTEGER NOT NULL CHECK(product IN (0, 1, 2, 3)), product INTEGER NOT NULL CHECK(product IN (0, 1, 2, 3)),
type INTEGER NOT NULL CHECK(type IN (0, 1)), type INTEGER NOT NULL CHECK(type IN (0, 1)),
price REAL NOT NULL price REAL NOT NULL,
traded_at DATETIME NOT NULL traded_at DATETIME NOT NULL
); );
CREATE TABLE IF NOT EXISTS position ( CREATE TABLE IF NOT EXISTS position (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
company_id INTEGER NOT NULL, company_id INTEGER NOT NULL,
currency_id INTEGER NOT NULL, currency_id INTEGER NOT NULL,
shares INTEGER NOT NULL, shares INTEGER NOT NULL,
weight REAL NOT NULL, weight REAL NOT NULL,
CostBases REAL NOT NULL, cost_basis REAL NOT NULL
); );
CREATE TABLE IF NOT EXISTS companies ( CREATE TABLE IF NOT EXISTS companies (

View File

@@ -3,24 +3,50 @@ package database
import ( import (
"Portifolio/internal/model" "Portifolio/internal/model"
"database/sql" "database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
) )
func GetTrades(db *sql.DB) ([]model.Trade, error) { func GetTrades(db *sql.DB) ([]model.Trade, error) {
rows, err := db.Query("SELECT id, company_id, currency_id, shares, product, type, price, traded_at FROM trades") rows, err := db.Query("SELECT company_id, currency_id, shares, product, type, price, traded_at FROM trades")
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer rows.Close() defer rows.Close()
var trades []model.Trade var trades []model.Trade
for rows.Next() { for rows.Next() {
var TickerInt int
var CurrencyInt int
var TypeInt int
var t model.Trade var t model.Trade
err := rows.Scan(&t.Ticker, &t.Currency, &t.Shares, &t.Product, &t.Type, &t.Price, &t.Date) err := rows.Scan(&TickerInt, &CurrencyInt, &t.Shares, &t.Product, &TypeInt, &t.Price, &t.Date)
if err != nil { if err != nil {
return nil, err return nil, err
} }
company, err := GetCompanyByID(db, TickerInt)
if err != nil {
return nil, err
}
currency, err := GetCurrencyByID(db, CurrencyInt)
if err != nil {
return nil, err
}
t.Currency = currency
t.Ticker = *company
switch TypeInt {
case 0:
t.Type = model.TradeType(false)
case 1:
t.Type = model.TradeType(true)
default:
return nil, fmt.Errorf("failed to convert given Type int to bool of trade type.")
}
trades = append(trades, t) trades = append(trades, t)
} }
if err = rows.Err(); err != nil { if err = rows.Err(); err != nil {

View File

@@ -5,6 +5,7 @@ import (
"Portifolio/internal/model" "Portifolio/internal/model"
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt"
"net/http" "net/http"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
@@ -20,10 +21,35 @@ func AddTradeHandler(db *sql.DB) http.HandlerFunc {
err := req.Validate() err := req.Validate()
if err != nil { if err != nil {
http.Error(w, "invalid json", http.StatusBadRequest) http.Error(w, fmt.Sprintf("failed to validate trade: %s", err), http.StatusInternalServerError)
return return
} }
// check if currency is in the db.
currency, err := database.GetCurrencyByCode(db, req.Currency)
if err != nil {
http.Error(w, fmt.Sprintf("failed to find currency: %s", err), http.StatusInternalServerError)
return
}
// check if company is in the db.
company, err := database.GetCompanyByID(db, req.TickerId)
if err != nil {
http.Error(w, fmt.Sprintf("failed to find currency: %s", err), http.StatusInternalServerError)
return
}
trade := model.Trade{
Ticker: *company,
Shares: req.Shares,
Product: model.TradeProduct(req.Product),
Type: model.TradeType(req.Type),
Price: req.Price,
Currency: currency,
Date: req.Date,
}
database.InsertTrade(db, trade)
} }
} }
@@ -31,13 +57,13 @@ func GetTradeListHandler(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
tradeList, err := database.GetTrades(db) tradeList, err := database.GetTrades(db)
if err != nil { if err != nil {
http.Error(w, "failed to fetch trades", http.StatusInternalServerError) http.Error(w, fmt.Sprintf("failed to fetch trades:", err), http.StatusInternalServerError)
return return
} }
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(tradeList); err != nil { if err := json.NewEncoder(w).Encode(tradeList); err != nil {
http.Error(w, "failed to encode trades", http.StatusInternalServerError) http.Error(w, fmt.Sprintf("failed to encode trades: %s", err), http.StatusInternalServerError)
return return
} }
} }

View File

@@ -41,13 +41,13 @@ type Trade struct {
} }
type AddTradeRequest struct { type AddTradeRequest struct {
TickerId int TickerId int `json:"ticker_id"`
Shares int Shares int `json:"shares"`
Product int Product int `json:"product"`
Type bool Type bool `json:"type"`
Price float64 Price float64 `json:"price"`
Currency string Currency string `json:"currency"`
Date time.Time Date time.Time `json:"date"`
} }
func (r *AddTradeRequest) Validate() error { func (r *AddTradeRequest) Validate() error {