-
Notifications
You must be signed in to change notification settings - Fork 385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds pg implementations for admin GetTree(id) and CreateTree #1305
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1305 +/- ##
==========================================
- Coverage 61.09% 60.32% -0.78%
==========================================
Files 125 127 +2
Lines 10070 10091 +21
==========================================
- Hits 6152 6087 -65
- Misses 3224 3324 +100
+ Partials 694 680 -14
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Vishal, thanks for pushing on the PG implementation!
A few quick comments inline
server/postgres_storage_provider.go
Outdated
"github.com/google/trillian/storage" | ||
"github.com/google/trillian/storage/postgres" | ||
|
||
// Load MySQL driver |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Load PG driver :)
server/postgres_storage_provider.go
Outdated
) | ||
|
||
var ( | ||
pgConnStr = flag.String("pg_uri", "user=postgres dbname=test port=5432 sslmode=disable", "Connection string for Postgres database") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe change the flag name to match too?
It's not really a URI any more by the looks of things.
storage/postgres/admin_storage.go
Outdated
|
||
var ( | ||
// ErrNotImplemented is an error indicating a function's implementation has not been completed | ||
ErrNotImplemented = errors.New("not implemented") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can probably be unexported?
storage/postgres/testdb/testdb.go
Outdated
|
||
"github.com/google/trillian/testonly" | ||
|
||
_ "github.com/lib/pq" // mysql driver |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
postgres driver
} | ||
} | ||
|
||
func cleanTestDB(db *sql.DB) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could pass T
in here, and call t.Helper()
as the first line, and t.Fatal
rather than panic
.
storage/postgres/tree_storage.go
Outdated
func OpenDB(dbURL string) (*sql.DB, error) { | ||
db, err := sql.Open("postgres", dbURL) | ||
if err != nil { | ||
// Don't log uri as it could contain credentials |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't log xxx
storage/storage_helpers.go
Outdated
import ( | ||
"database/sql" | ||
"fmt" | ||
time "time" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to rename time
to time
:)
storage/storage_helpers.go
Outdated
|
||
// FromMillisSinceEpoch converts an UNIX typestamp to a time struct | ||
func FromMillisSinceEpoch(ts int64) time.Time { | ||
secs := int64(ts / 1000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can just be return time.Unix(0, ts*1000000)
storage/storage_helpers.go
Outdated
@@ -0,0 +1,162 @@ | |||
// Copyright 2018 Google Inc. All Rights Reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should go under storage/sql
or something - explicitly helpers for golang SQL compatible implementations?
@@ -161,7 +158,7 @@ func (t *adminTX) GetTree(ctx context.Context, treeID int64) (*trillian.Tree, er | |||
defer stmt.Close() | |||
|
|||
// GetTree is an entry point for most RPCs, let's provide somewhat nicer error messages. | |||
tree, err := readTree(stmt.QueryRowContext(ctx, treeID)) | |||
tree, err := storage.ReadTree(stmt.QueryRowContext(ctx, treeID)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if this is a good idea or not...
OTOH it does promote reuse and reduce boilerplate, but on the other it forces some restrictions on implementations, maybe that's a good trade off to make until we discover a scenario where it doesn't work, let's see what others think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, definitely wasn't sure how much to pull out/leave in. My general understanding was that db/sql abstracted most differences away to only being at the query level but I could be wrong about that (especially with types, etc.)
storage/storage_helpers.go
Outdated
return nil | ||
} | ||
|
||
// Row defines a common interface between sql.Row and sql.Rows(!), so we have to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this comment got a bit mangled. It was originally "There's no common interface between sql.Row and sql.Rows(!), so we have to define one."
storage/storage_helpers.go
Outdated
} | ||
|
||
// ValidateStorageSettings checks for storage settings and returns an error if they exist | ||
func ValidateStorageSettings(tree *trillian.Tree) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't seem like this should be a general helper, since storage_settings is supposed to be specific to individual storage implementations.
storage/postgres/testdb/testdb.go
Outdated
} | ||
|
||
// skipIfNoPG is a test helper that skips tests that require a local PG. | ||
func skipIfNoPG(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
skipIfNoPG
is unused
10b0858
to
670d565
Compare
storage/sql.go
Outdated
} | ||
|
||
// Let's make sure we didn't mismatch any of the casts above | ||
ok := tree.TreeState.String() == treeState |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just make this:
ok := tree.TreeState.String() == treestate &&
tree.TreeType.String() == treeType &&
tree.HashStrategy.String() == hashStrategy &&
...
?
670d565
to
0941a7a
Compare
0941a7a
to
cbc4d6a
Compare
Thanks, Vishal! |
This PR introduces a partial implementation for admin storage in postgres. Particularly, it implements the
CreateTree
andGetTree(id)
methods.Much of the logic is borrowed heavily from the MySQL methods (including validation and setup) so I tried to pull out common helpers wherever I could. That being said, I think there were even further commonalities I could pull out but I worried that that'd be too big a change for this PR (let me know if you feel otherwise).
As far as testing, I copied most of the logic in mysql's storage tests but have yet to build our a test driver. I figured I'd leave that to another PR as this one was getting fairly large.
Issue: #1298