diff --git a/chiv.go b/chiv.go index d8278f9..1a45ab6 100644 --- a/chiv.go +++ b/chiv.go @@ -1,10 +1,81 @@ +// Package chiv archives arbitrarily large relational database tables to Amazon S3. package chiv import ( + "context" + "database/sql" + "github.com/aws/aws-sdk-go/service/s3/s3manager" ) -func Archive(uploader *s3manager.Uploader) { +type Archiver struct { + db *sql.DB + s3 *s3manager.Uploader + format Format // TODO WithFormat(Format) Option + // TODO other options like batch size... in bytes or rows? +} + +type Option func(*Archiver) + +type Format int + +const ( + CSV Format = iota + JSON +) + +const ( + DefaultFormat = CSV +) + +// NewArchiver constructs an Archiver with the given database connection, S3 uploader and options. +func NewArchiver(db *sql.DB, s3 *s3manager.Uploader, options ...Option) *Archiver { + a := Archiver{ + db: db, + s3: s3, + format: DefaultFormat, + } + + for _, option := range options { + option(&a) + } + + return &a +} + +// Archive a database table to S3. +func (a *Archiver) Archive(table string, options ...Option) error { + return a.ArchiveWithContext(context.Background(), table, options...) +} + +// Archive a database table to S3 with context. +func (a *Archiver) ArchiveWithContext(ctx context.Context, table string, options ...Option) error { + archiver := archiver{ + db: a.db, // TODO do these need to be top level or use archiver.config.db and archiver.config.s3? + s3: a.s3, + ctx: ctx, + config: a, + } + + for _, option := range options { + option(archiver.config) + } + + return archiver.archive(table) +} + +type archiver struct { + db *sql.DB + s3 *s3manager.Uploader + ctx context.Context + config *Archiver +} + +func (a *archiver) archive(table string) error { + + // TODO the work + // db cursor selecting: ??? + // s3 streaming: https://docs.aws.amazon.com/code-samples/latest/catalog/go-s3-upload_arbitrary_sized_stream.go.html - //https://docs.aws.amazon.com/code-samples/latest/catalog/go-s3-upload_arbitrary_sized_stream.go.html + return nil // TODO return size or some other info along w/ error? } diff --git a/chiv_test.go b/chiv_test.go index a4444d9..586731f 100644 --- a/chiv_test.go +++ b/chiv_test.go @@ -1,3 +1,5 @@ +// Package chiv_test includes integration tests external to package chiv +// and relies on external services postgres and s3 (localstack) via CodeShip. package chiv_test import ( @@ -9,4 +11,4 @@ import ( func TestArchive(t *testing.T) { chiv.Archive() t.Log("test test test") -} \ No newline at end of file +}