Files
openaccounting-server/core/model/db/price.go
Patrick Nagurny e2dd29259f initial commit
2018-10-19 15:31:41 -04:00

157 lines
3.6 KiB
Go

package db
import (
"database/sql"
"errors"
"github.com/openaccounting/oa-server/core/model/types"
"github.com/openaccounting/oa-server/core/util"
"time"
)
type PriceInterface interface {
InsertPrice(*types.Price) error
GetPriceById(string) (*types.Price, error)
DeletePrice(string) error
GetPricesNearestInTime(string, time.Time) ([]*types.Price, error)
GetPricesByCurrency(string, string) ([]*types.Price, error)
}
const priceFields = "LOWER(HEX(p.id)),LOWER(HEX(p.orgId)),p.currency,p.date,p.inserted,p.updated,p.price"
func (db *DB) InsertPrice(price *types.Price) error {
price.Inserted = time.Now()
price.Updated = price.Inserted
if price.Date.IsZero() {
price.Date = price.Inserted
}
query := "INSERT INTO price(id,orgId,currency,date,inserted,updated,price) VALUES(UNHEX(?),UNHEX(?),?,?,?,?,?)"
_, err := db.Exec(
query,
price.Id,
price.OrgId,
price.Currency,
util.TimeToMs(price.Date),
util.TimeToMs(price.Inserted),
util.TimeToMs(price.Updated),
price.Price,
)
return err
}
func (db *DB) GetPriceById(id string) (*types.Price, error) {
var p types.Price
var date int64
var inserted int64
var updated int64
err := db.QueryRow("SELECT "+priceFields+" FROM price p WHERE id = UNHEX(?)", id).
Scan(&p.Id, &p.OrgId, &p.Currency, &date, &inserted, &updated, &p.Price)
switch {
case err == sql.ErrNoRows:
return nil, errors.New("Price not found")
case err != nil:
return nil, err
default:
p.Date = util.MsToTime(date)
p.Inserted = util.MsToTime(inserted)
p.Updated = util.MsToTime(updated)
return &p, nil
}
}
func (db *DB) DeletePrice(id string) error {
query := "DELETE FROM price WHERE id = UNHEX(?)"
_, err := db.Exec(query, id)
return err
}
func (db *DB) GetPricesNearestInTime(orgId string, date time.Time) ([]*types.Price, error) {
qSelect := "SELECT " + priceFields
qFrom := " FROM price p"
qJoin := " LEFT OUTER JOIN price p2 ON p.currency = p2.currency AND p.orgId = p2.orgId AND ABS(CAST(p.date AS SIGNED) - ?) > ABS(CAST(p2.date AS SIGNED) - ?)"
qWhere := " WHERE p2.id IS NULL AND p.orgId = UNHEX(?)"
query := qSelect + qFrom + qJoin + qWhere
rows, err := db.Query(query, util.TimeToMs(date), util.TimeToMs(date), orgId)
if err != nil {
return nil, err
}
defer rows.Close()
prices := make([]*types.Price, 0)
for rows.Next() {
var date int64
var inserted int64
var updated int64
p := new(types.Price)
err = rows.Scan(&p.Id, &p.OrgId, &p.Currency, &date, &inserted, &updated, &p.Price)
if err != nil {
return nil, err
}
p.Date = util.MsToTime(date)
p.Inserted = util.MsToTime(inserted)
p.Updated = util.MsToTime(updated)
prices = append(prices, p)
}
err = rows.Err()
if err != nil {
return nil, err
}
return prices, nil
}
func (db *DB) GetPricesByCurrency(orgId string, currency string) ([]*types.Price, error) {
qSelect := "SELECT " + priceFields
qFrom := " FROM price p"
qWhere := " WHERE p.orgId = UNHEX(?) AND p.currency = ?"
pOrder := " ORDER BY date ASC"
query := qSelect + qFrom + qWhere + pOrder
rows, err := db.Query(query, orgId, currency)
if err != nil {
return nil, err
}
defer rows.Close()
prices := make([]*types.Price, 0)
for rows.Next() {
var date int64
var inserted int64
var updated int64
p := new(types.Price)
err = rows.Scan(&p.Id, &p.OrgId, &p.Currency, &date, &inserted, &updated, &p.Price)
if err != nil {
return nil, err
}
p.Date = util.MsToTime(date)
p.Inserted = util.MsToTime(inserted)
p.Updated = util.MsToTime(updated)
prices = append(prices, p)
}
err = rows.Err()
if err != nil {
return nil, err
}
return prices, nil
}