From 5a558c0d6fb9672bbe5e8cf6c806d155bcb3592d Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Fri, 24 Mar 2017 21:25:16 +0000 Subject: [PATCH] Implement Authable statements for improved logging --- db/db.go | 11 ++- sql/ast.go | 4 + sql/auth.gen.go | 131 ++++++++++++++++++++++++++++ sql/auth.gen.go.tmpl | 23 +++++ sql/auth.gen.json | 33 +++++++ sql/gen.go | 1 + sql/kill.gen.go | 203 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 sql/auth.gen.go create mode 100644 sql/auth.gen.go.tmpl create mode 100644 sql/auth.gen.json create mode 100644 sql/kill.gen.go diff --git a/db/db.go b/db/db.go index 805b6e8a..53d57233 100644 --- a/db/db.go +++ b/db/db.go @@ -267,11 +267,18 @@ func (e *executor) execute(ctx context.Context, quit <-chan bool, send chan<- *R // query, along with the query execution // speed, so we can analyse slow queries. - log.WithPrefix("sql").WithFields(map[string]interface{}{ + log := log.WithPrefix("sql").WithFields(map[string]interface{}{ "id": e.web.Get("id"), "kind": e.web.Get("auth").(*cnf.Auth).Kind, "auth": e.web.Get("auth").(*cnf.Auth).Data, - }).Debugln(stm) + }) + + if stm, ok := stm.(sql.AuthableStatement); ok { + ns, db := stm.Auth() + log = log.WithField("ns", ns).WithField("db", db) + } + + log.Debugln(stm) // Check to see if the current statement is // a TRANSACTION statement, and if it is diff --git a/sql/ast.go b/sql/ast.go index 523d77cf..c97ddf19 100644 --- a/sql/ast.go +++ b/sql/ast.go @@ -38,6 +38,10 @@ type Statements []Statement // Other // -------------------------------------------------- +type AuthableStatement interface { + Auth() (string, string) +} + type KillableStatement interface { Begin() Cease() diff --git a/sql/auth.gen.go b/sql/auth.gen.go new file mode 100644 index 00000000..a328d5ef --- /dev/null +++ b/sql/auth.gen.go @@ -0,0 +1,131 @@ +// Code generated by https://github.com/abcum/tmpl +// Source file: auth.gen.go.tmpl +// DO NOT EDIT! + +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sql + +func (s *UseStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *InfoStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *LetStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *ReturnStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *LiveStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *SelectStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *CreateStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *UpdateStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *DeleteStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *RelateStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *DefineNamespaceStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *RemoveNamespaceStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *DefineDatabaseStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *RemoveDatabaseStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *DefineLoginStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *RemoveLoginStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *DefineTokenStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *RemoveTokenStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *DefineScopeStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *RemoveScopeStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *DefineTableStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *RemoveTableStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *DefineFieldStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *RemoveFieldStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *DefineIndexStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *RemoveIndexStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *DefineViewStatement) Auth() (string, string) { + return s.NS, s.DB +} + +func (s *RemoveViewStatement) Auth() (string, string) { + return s.NS, s.DB +} diff --git a/sql/auth.gen.go.tmpl b/sql/auth.gen.go.tmpl new file mode 100644 index 00000000..e732ae07 --- /dev/null +++ b/sql/auth.gen.go.tmpl @@ -0,0 +1,23 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sql + +{{with $types := .}}{{range $k := $types}} + +func (s *{{$k.name}}Statement) Auth() (string, string) { + return s.NS, s.DB +} + +{{end}}{{end}} diff --git a/sql/auth.gen.json b/sql/auth.gen.json new file mode 100644 index 00000000..ad06c467 --- /dev/null +++ b/sql/auth.gen.json @@ -0,0 +1,33 @@ +[ + { "name": "Use" }, + { "name": "Info" }, + + { "name": "Let" }, + { "name": "Return" }, + + { "name": "Live" }, + { "name": "Select" }, + { "name": "Create" }, + { "name": "Update" }, + { "name": "Delete" }, + { "name": "Relate" }, + + { "name": "DefineNamespace" }, + { "name": "RemoveNamespace" }, + { "name": "DefineDatabase" }, + { "name": "RemoveDatabase" }, + { "name": "DefineLogin" }, + { "name": "RemoveLogin" }, + { "name": "DefineToken" }, + { "name": "RemoveToken" }, + { "name": "DefineScope" }, + { "name": "RemoveScope" }, + { "name": "DefineTable" }, + { "name": "RemoveTable" }, + { "name": "DefineField" }, + { "name": "RemoveField" }, + { "name": "DefineIndex" }, + { "name": "RemoveIndex" }, + { "name": "DefineView" }, + { "name": "RemoveView" } +] diff --git a/sql/gen.go b/sql/gen.go index ef310b68..f04ced49 100644 --- a/sql/gen.go +++ b/sql/gen.go @@ -15,6 +15,7 @@ package sql //go:generate go get -u github.com/abcum/tmpl +//go:generate tmpl -file=auth.gen.json auth.gen.go.tmpl //go:generate tmpl -file=kill.gen.json kill.gen.go.tmpl //go:generate go get -u github.com/ugorji/go/codec/codecgen diff --git a/sql/kill.gen.go b/sql/kill.gen.go new file mode 100644 index 00000000..0dc8f0fb --- /dev/null +++ b/sql/kill.gen.go @@ -0,0 +1,203 @@ +// Code generated by https://github.com/abcum/tmpl +// Source file: kill.gen.go.tmpl +// DO NOT EDIT! + +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sql + +import ( + "time" +) + +func (s *SelectStatement) Begin() { + if s.Timeout == 0 { + return + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + s.killable.ticker = time.AfterFunc(s.Timeout, func() { + s.killable.ticker.Stop() + s.killable.ticker = nil + close(s.killable.closer) + }) +} + +func (s *SelectStatement) Cease() { + if s.Timeout == 0 { + return + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + if s.killable.ticker != nil { + s.killable.ticker.Stop() + } +} + +func (s *SelectStatement) Timedout() <-chan struct{} { + if s.Timeout == 0 { + return nil + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + return s.killable.closer +} + +func (s *CreateStatement) Begin() { + if s.Timeout == 0 { + return + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + s.killable.ticker = time.AfterFunc(s.Timeout, func() { + s.killable.ticker.Stop() + s.killable.ticker = nil + close(s.killable.closer) + }) +} + +func (s *CreateStatement) Cease() { + if s.Timeout == 0 { + return + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + if s.killable.ticker != nil { + s.killable.ticker.Stop() + } +} + +func (s *CreateStatement) Timedout() <-chan struct{} { + if s.Timeout == 0 { + return nil + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + return s.killable.closer +} + +func (s *UpdateStatement) Begin() { + if s.Timeout == 0 { + return + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + s.killable.ticker = time.AfterFunc(s.Timeout, func() { + s.killable.ticker.Stop() + s.killable.ticker = nil + close(s.killable.closer) + }) +} + +func (s *UpdateStatement) Cease() { + if s.Timeout == 0 { + return + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + if s.killable.ticker != nil { + s.killable.ticker.Stop() + } +} + +func (s *UpdateStatement) Timedout() <-chan struct{} { + if s.Timeout == 0 { + return nil + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + return s.killable.closer +} + +func (s *DeleteStatement) Begin() { + if s.Timeout == 0 { + return + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + s.killable.ticker = time.AfterFunc(s.Timeout, func() { + s.killable.ticker.Stop() + s.killable.ticker = nil + close(s.killable.closer) + }) +} + +func (s *DeleteStatement) Cease() { + if s.Timeout == 0 { + return + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + if s.killable.ticker != nil { + s.killable.ticker.Stop() + } +} + +func (s *DeleteStatement) Timedout() <-chan struct{} { + if s.Timeout == 0 { + return nil + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + return s.killable.closer +} + +func (s *RelateStatement) Begin() { + if s.Timeout == 0 { + return + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + s.killable.ticker = time.AfterFunc(s.Timeout, func() { + s.killable.ticker.Stop() + s.killable.ticker = nil + close(s.killable.closer) + }) +} + +func (s *RelateStatement) Cease() { + if s.Timeout == 0 { + return + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + if s.killable.ticker != nil { + s.killable.ticker.Stop() + } +} + +func (s *RelateStatement) Timedout() <-chan struct{} { + if s.Timeout == 0 { + return nil + } + if s.killable.closer == nil { + s.killable.closer = make(chan struct{}) + } + return s.killable.closer +}