-
Notifications
You must be signed in to change notification settings - Fork 13
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
Add MySQL storage and tests #5
Add MySQL storage and tests #5
Conversation
0aa680c
to
cd04701
Compare
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.
Stoked to see this up!
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 is an amazing contribution! Thanks so much for this! Here's some quick thoughts and I'll try to get time soon, hopefully early next week for more. :)
Bunch of comments inline. :)
I have some reservations about having an opinionated docker-compose front and center. Let me think more on that (maybe it's as simple as placing the compose file in storage/storagetest/?).
The cmd/cli.go -> parse/storage.go is interesting. What was the thinking there?
Also - don't forget to update the docs (docs/operations-guide.md) for the new storage backend. :)
storage/file/file.go
Outdated
@@ -20,6 +21,8 @@ type FileStorage struct { | |||
path string | |||
} | |||
|
|||
var _ storage.AllStorage = (*FileStorage)(nil) |
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.
Curious what's the reason for this?
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.
Convention that serves both as a "compile time check" and as a form of documentation for code readers/reviewers that FileStorage
implements storage.AllStorage
interface.
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 think this creates an unnecessary coupling. How do you feel about removing it? As Go is statically typed an implementation must conform to it's use. AllStorage
isn't particularly useful outside of main.go
so I'd not like to couple these.
Let me know what you think. :)
storage/file/file.go
Outdated
return tokens, decodeJSONfile(s.tokensFilename(name), tokens) | ||
err := decodeJSONfile(s.tokensFilename(name), tokens) | ||
if err != nil { | ||
return nil, err |
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.
Any problem with returning a non-nil empty token — most callers are going to check for errors anyway?
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.
A convention I've seen many projects use is to try (when possible) to always return zero-values when error is non-nil. In this case, the zero-value of a pointer is nil
.
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.
So I'm fine with this specific code change, although its a bit verbose. But in general I don't think its necessary to add a bunch of boilerplate to assure a zero-values for an error. Discussed here: https://macadmins.slack.com/archives/C07ME1284/p1663867171949419
I believe I've address all the comments.
I've moved it to
Originally I didn't want mysql imports in
Done. I really appreciate the feedback! |
6952196
to
bb4cb0f
Compare
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.
sorry for the unacceptably huge delay! just a few changes. would love your input on the general Go idiomatic/convention stuff — but it sounds like we might disagree on a few small things :). hopefully we can resolve!
parse/storage.go
Outdated
@@ -0,0 +1,28 @@ | |||
package parse |
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 like the idea of moving this out of the cmd/
tree. But can we rename this package to just cli
to match micromdm/nanomdm@ff8b7af?
storage/file/file.go
Outdated
@@ -20,6 +21,8 @@ type FileStorage struct { | |||
path string | |||
} | |||
|
|||
var _ storage.AllStorage = (*FileStorage)(nil) |
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 think this creates an unnecessary coupling. How do you feel about removing it? As Go is statically typed an implementation must conform to it's use. AllStorage
isn't particularly useful outside of main.go
so I'd not like to couple these.
Let me know what you think. :)
storage/file/file.go
Outdated
return tokens, decodeJSONfile(s.tokensFilename(name), tokens) | ||
err := decodeJSONfile(s.tokensFilename(name), tokens) | ||
if err != nil { | ||
return nil, err |
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.
So I'm fine with this specific code change, although its a bit verbose. But in general I don't think its necessary to add a bunch of boilerplate to assure a zero-values for an error. Discussed here: https://macadmins.slack.com/archives/C07ME1284/p1663867171949419
storage/mysql/mysql.go
Outdated
if err != nil { | ||
if errors.Is(err, sql.ErrNoRows) { | ||
// an 'empty' config is valid | ||
return &client.Config{}, nil |
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.
Hmm, good call-out. I think the file-storage should be changed to match actually:
No config (missing) = nil
Present config (including an empty BaseURL) = returned.
They're treated the same in the config retriever interface implementation, as it happens. This should probably be documented there:
Lines 23 to 25 in a7538c5
type ConfigRetriever interface { | |
RetrieveConfig(context.Context, string) (*Config, error) | |
} |
I've amended the two storage implementations to behave this way, and added a test for |
@jessepeterson One last change that can be added to this PR, or open a separate one if this one is merged-as is: mikermcneil#1 Your call. |
@lucasmrod let's do a separate PR and keep this contained :) also I think you need to 'request review' or whatever - it's showing as changes still requested :) thanks again! |
Cool. I'll create another PR once this one is merged 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.
thanks much for this contribution @lucasmrod !
@@ -21,7 +21,11 @@ type Config struct { | |||
} | |||
|
|||
type ConfigRetriever interface { | |||
RetrieveConfig(context.Context, string) (*Config, error) | |||
// RetrieveConfig reads the JSON DEP config of a DEP name. |
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.
❤️
Hi folks.
This PR implements a MySQL storage, issue #4.
I've added tests that can be run on any future storage (which caught a small bug in the
FileStorage
).