diff --git a/interleaver/interfaces.go b/interleaver/interfaces.go index dd2c1b5..a83dd76 100644 --- a/interleaver/interfaces.go +++ b/interleaver/interfaces.go @@ -4,7 +4,12 @@ package main -import "bitbucket.org/s_l_teichmann/mtredisalize/common" +import ( + "fmt" + "bitbucket.org/s_l_teichmann/mtredisalize/common" +) + +var NoMoreBlocksErr = fmt.Errorf("No more blocks.") type ( Block struct { @@ -13,8 +18,9 @@ type ( } BlocKProducer interface { + // Returns next block. + // error is NoMoreBlocksErr if it run out of blocks. Next() (Block, error) - HasNext() bool Close() error } diff --git a/interleaver/main.go b/interleaver/main.go new file mode 100644 index 0000000..0f2c2a1 --- /dev/null +++ b/interleaver/main.go @@ -0,0 +1,9 @@ +// Copyright 2014 by Sascha L. Teichmann +// Use of this source code is governed by the MIT license +// that can be found in the LICENSE file. + +package main + +func main() { + // TODO: Implement me! +} diff --git a/interleaver/sqlite.go b/interleaver/sqlite.go new file mode 100644 index 0000000..6ed5f5e --- /dev/null +++ b/interleaver/sqlite.go @@ -0,0 +1,75 @@ +// Copyright 2014 by Sascha L. Teichmann +// Use of this source code is governed by the MIT license +// that can be found in the LICENSE file. + +package main + +import ( + "database/sql" + "os" + + "bitbucket.org/s_l_teichmann/mtredisalize/common" + + _ "github.com/mattn/go-sqlite3" +) + +const ( + fetchSql = "SELECT pos, data FROM blocks" +) + +type SQLiteBlockProducer struct { + db *sql.DB + rows *sql.Rows + splitter common.KeySplitter +} + +func NewSQLiteBlockProducer(path string, splitter common.KeySplitter) (sbp *SQLiteBlockProducer, err error) { + + // check if we can stat it -> exists. + if _, err = os.Stat(path); err != nil { + return + } + + var db *sql.DB + if db, err = sql.Open("sqlite3", path); err != nil { + return + } + + var rows *sql.Rows + if rows, err = db.Query(fetchSql); err != nil { + db.Close() + return + } + + sbp = &SQLiteBlockProducer{ + db: db, + rows: rows, + splitter: splitter} + + return +} + +func (sbp *SQLiteBlockProducer) Next() (block Block, err error) { + if sbp.rows == nil { + err = NoMoreBlocksErr + return + } + if sbp.rows.Next() { + var key int64 + if err = sbp.rows.Scan(&key, &block.Data); err == nil { + block.Coord = sbp.splitter(key) + } + } else { + sbp.rows.Close() + sbp.rows = nil + err = NoMoreBlocksErr + } + return +} + +func (sbp *SQLiteBlockProducer) Close() error { + if sbp.rows != nil { + sbp.rows.Close() + } + return sbp.db.Close() +}