<commit_before>package sqlitecache

import (
	"database/sql"
	"fmt"
	"github.com/aktau/gofinance/fquery"
	"github.com/aktau/gofinance/util"
	"github.com/coopernurse/gorp"
	_ "github.com/mattn/go-sqlite3"
	"log"
	"os"
	"strings"
	"sync"
	"time"
)

/* a version of the fquery.HistEntry struct with a symbol appended,
 * so we can query it easier. */
type dbHistEntry struct {
	Symbol   string
	Date     time.Time
	Open     float64
	Close    float64
	AdjClose float64
	High     float64
	Low      float64
	Volume   int64
}

type dbHistMeta struct {
	Symbol string
	Amount int64

	MinDate int64
	MaxDate int64

	/* processed versions of MinDate/MaxDate */
	rMinDate time.Time
	rMaxDate time.Time
}

var (
	VERBOSITY = 0
)

type SqliteCache struct {
	fquery.Source

	gorp        *gorp.DbMap
	quoteExpiry time.Duration
}

func New(path string, src fquery.Source) (*SqliteCache, error) {
	db, err := sql.Open("sqlite3", path)
	if err != nil {
		return nil, err
	}

	dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
	if VERBOSITY >= 2 {
		dbmap.TraceOn("", log.New(os.Stdout, "dbmap: ", log.Lmicroseconds))
	}

	c := &SqliteCache{src, dbmap, 30 * time.Second}

	c.gorp.AddTableWithName(fquery.Quote{}, "quotes").SetKeys(false, "Symbol")
	c.gorp.AddTableWithName(dbHistEntry{}, "histquotes").SetKeys(false, "Symbol", "Date")

	err = dbmap.CreateTablesIfNotExists()
	if err != nil {
		c.Close()
		return nil, err
	}

	return c, nil
}

func (c *SqliteCache) SetQuoteExpiry(dur time.Duration) {
	c.quoteExpiry = dur
}

func (c *SqliteCache) HasQuote(symbol string) bool {
	return false
}

func (c *SqliteCache) HasHist(symbol string, start *time.Time, end *time.Time) bool {
	return false
}

func (c *SqliteCache) Close() error {
	return c.gorp.Db.Close()
}

/* TODO: escape your strings, symbols could be user input */
func (c *SqliteCache) Quote(symbols []string) ([]fquery.Quote, error) {
	/* fetch all the quotes we have */
	quotedSymbols := quoteSymbols(symbols)
<commit_msg>sqlitecache: hist, create index on Date column<commit_after>package sqlitecache

import (
	"database/sql"
	"fmt"
	"github.com/aktau/gofinance/fquery"
	"github.com/aktau/gofinance/util"
	"github.com/coopernurse/gorp"
	_ "github.com/mattn/go-sqlite3"
	"log"
	"os"
	"strings"
	"sync"
	"time"
)

/* a version of the fquery.HistEntry struct with a symbol appended,
 * so we can query it easier. */
type dbHistEntry struct {
	Symbol   string
	Date     time.Time
	Open     float64
	Close    float64
	AdjClose float64
	High     float64
	Low      float64
	Volume   int64
}

type dbHistMeta struct {
	Symbol string
	Amount int64

	MinDate int64
	MaxDate int64

	/* processed versions of MinDate/MaxDate */
	rMinDate time.Time
	rMaxDate time.Time
}

var (
	VERBOSITY = 0
)

type SqliteCache struct {
	fquery.Source

	gorp        *gorp.DbMap
	quoteExpiry time.Duration
}

func New(path string, src fquery.Source) (*SqliteCache, error) {
	db, err := sql.Open("sqlite3", path)
	if err != nil {
		return nil, err
	}

	dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
	if VERBOSITY >= 2 {
		dbmap.TraceOn("", log.New(os.Stdout, "dbmap: ", log.Lmicroseconds))
	}

	c := &SqliteCache{src, dbmap, 30 * time.Second}

	c.gorp.AddTableWithName(fquery.Quote{}, "quotes").SetKeys(false, "Symbol")
	c.gorp.AddTableWithName(dbHistEntry{}, "histquotes").SetKeys(false, "Symbol", "Date")

	err = c.gorp.CreateTablesIfNotExists()
	if err != nil {
		c.Close()
		return nil, err
	}

	/* support date range queries over all symbols */
	_, err = c.gorp.Exec(`CREATE INDEX IF NOT EXISTS hq_date_idx ON histquotes (Date)`)
	if err != nil {
		c.Close()
		return nil, err
	}

	return c, nil
}

func (c *SqliteCache) SetQuoteExpiry(dur time.Duration) {
	c.quoteExpiry = dur
}

func (c *SqliteCache) HasQuote(symbol string) bool {
	return false
}

func (c *SqliteCache) HasHist(symbol string, start *time.Time, end *time.Time) bool {
	return false
}

func (c *SqliteCache) Close() error {
	return c.gorp.Db.Close()
}

/* TODO: escape your strings, symbols could be user input */
func (c *SqliteCache) Quote(symbols []string) ([]fquery.Quote, error) {
	/* fetch all the quotes we have */
	quotedSymbols := quoteSymbols(symbols)

{'fraction_non_alphanumeric': 0.12760354321283218, 'fraction_numerical': 0.011491501077328227, 'mean_word_length': 3.830057803468208, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '2928823', 'n_tokens_mistral': 1663, 'n_tokens_neox': 1592, 'n_words': 410}