<commit_before>// Copyright (C) 2014 <NAME> <<EMAIL>>
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package lastfm

import (
	"database/sql"
	"strings"
	"time"
)

type Track struct {
	Id     int64
	Artist string
	Album  string
	Title  string
	Time   time.Time
}

var schema = []string{
	`CREATE TABLE IF NOT EXISTS lastfm_tracks (
		id INT(10) NOT NULL AUTO_INCREMENT,
		time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
		artist VARCHAR(100) NOT NULL,
		album VARCHAR(100) NOT NULL,
		title VARCHAR(100) NOT NULL,
		PRIMARY KEY (id),
		INDEX time (time),
		INDEX artist_album_title (artist, album, title)
	) ENGINE=InnoDB DEFAULT CHARSET=utf8;`,
}

var schemaSqlite3 = []string{
	`CREATE TABLE IF NOT EXISTS lastfm_tracks (
		id INTEGER PRIMARY KEY,
		time TIMESTAMP NOT NULL,
		artist VARCHAR(100) NOT NULL,
		album VARCHAR(100) NOT NULL,
		title VARCHAR(100) NOT NULL
	)`,
	`CREATE INDEX IF NOT EXISTS time ON lastfm_tracks (time)`,
	`CREATE INDEX IF NOT EXISTS artist_album_title ON lastfm_tracks (artist, album, title)`,
}

type Database interface {
	Setup() error

	StoreTracks(ts []Track) error
	GetLastTrack(filter Track) (Track, error)
}

type sqlDatabase struct {
	Driver string
	Db     *sql.DB
}

func (d *sqlDatabase) Setup() error {
	var err error
	s := schema
	if d.Driver == "sqlite3" {
		s = schemaSqlite3
	}
	for _, q := range s {
		if _, err = d.Db.Exec(q); err != nil {
			return err
		}
	}
	return err
}

func (d *sqlDatabase) StoreTracks(ts []Track) error {
	stmt, err := d.Db.Prepare(`INSERT INTO lastfm_tracks (time, artist, album, title) VALUES (?, ?, ?, ?)`)
	if err != nil {
		return err
	}
	for _, t := range ts {
		if t.Title == "" {
			continue
		}
		if _, err := stmt.Exec(t.Time, t.Artist, t.Album, t.Title); err != nil {
			return err
		}
	}
	return nil
}

func (d *sqlDatabase) GetLastTrack(filter Track) (Track, error) {
	cond := make([]string, 0)
	vars := make([]interface{}, 0)

	if filter.Artist != "" {
		cond = append(cond, "artist = ?")
		vars = append(vars, filter.Artist)
	}
	if filter.Album != "" {
		cond = append(cond, "album = ?")
		vars = append(vars, filter.Album)
	}
	if filter.Title != "" {
		cond = append(cond, "title = ?")
		vars = append(vars, filter.Title)
	}
<commit_msg>LastFM: Insert correctly sorted.<commit_after>// Copyright (C) 2014 <NAME> <<EMAIL>>
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package lastfm

import (
	"database/sql"
	"sort"
	"strings"
	"time"
)

type Track struct {
	Id     int64
	Artist string
	Album  string
	Title  string
	Time   time.Time
}

var schema = []string{
	`CREATE TABLE IF NOT EXISTS lastfm_tracks (
		id INT(10) NOT NULL AUTO_INCREMENT,
		time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
		artist VARCHAR(100) NOT NULL,
		album VARCHAR(100) NOT NULL,
		title VARCHAR(100) NOT NULL,
		PRIMARY KEY (id),
		INDEX time (time),
		INDEX artist_album_title (artist, album, title)
	) ENGINE=InnoDB DEFAULT CHARSET=utf8;`,
}

var schemaSqlite3 = []string{
	`CREATE TABLE IF NOT EXISTS lastfm_tracks (
		id INTEGER PRIMARY KEY,
		time TIMESTAMP NOT NULL,
		artist VARCHAR(100) NOT NULL,
		album VARCHAR(100) NOT NULL,
		title VARCHAR(100) NOT NULL
	)`,
	`CREATE INDEX IF NOT EXISTS time ON lastfm_tracks (time)`,
	`CREATE INDEX IF NOT EXISTS artist_album_title ON lastfm_tracks (artist, album, title)`,
}

type Database interface {
	Setup() error

	StoreTracks(ts []Track) error
	GetLastTrack(filter Track) (Track, error)
}

type sqlDatabase struct {
	Driver string
	Db     *sql.DB
}

func (d *sqlDatabase) Setup() error {
	var err error
	s := schema
	if d.Driver == "sqlite3" {
		s = schemaSqlite3
	}
	for _, q := range s {
		if _, err = d.Db.Exec(q); err != nil {
			return err
		}
	}
	return err
}

type ByDate []Track

func (a ByDate) Len() int           { return len(a) }
func (a ByDate) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByDate) Less(i, j int) bool { return a[i].Time.Before(a[j].Time) }

func (d *sqlDatabase) StoreTracks(ts []Track) error {
	stmt, err := d.Db.Prepare(`INSERT INTO lastfm_tracks (time, artist, album, title) VALUES (?, ?, ?, ?)`)
	if err != nil {
		return err
	}
	sort.Sort(ByDate(ts))
	for _, t := range ts {
		if t.Title == "" {
			continue
		}
		if _, err := stmt.Exec(t.Time, t.Artist, t.Album, t.Title); err != nil {
			return err
		}
	}
	return nil
}

func (d *sqlDatabase) GetLastTrack(filter Track) (Track, error) {
	cond := make([]string, 0)
	vars := make([]interface{}, 0)

	if filter.Artist != "" {
		cond = append(cond, "artist = ?")
		vars = append(vars, filter.Artist)
	}
	if filter.Album != "" {
		cond = append(cond, "album = ?")
		vars = append(vars, filter.Album)
	}
	if filter.Title != "" {
		cond = append(cond, "title = ?")
		vars = append(vars, filter.Title)
	}

{'fraction_non_alphanumeric': 0.13554776150195996, 'fraction_numerical': 0.013204043738394884, 'mean_word_length': 3.5055762081784385, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '4406562', 'n_tokens_mistral': 1935, 'n_tokens_neox': 1762, 'n_words': 560}