You've already forked openaccounting-server
mirror of
https://github.com/openaccounting/oa-server.git
synced 2025-12-09 09:00:42 +13:00
157 lines
3.6 KiB
Go
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
|
||
|
|
}
|