diff --git a/db.go b/db.go index 0d07a16f6cd54ab5630a3bae2c6377af88e353aa..91d24ea6ee72ba54ddda96f4c32a2f258f576766 100644 --- a/db.go +++ b/db.go @@ -390,6 +390,9 @@ type Database interface { // ConnectionURL returns the data used to set up the adapter. ConnectionURL() ConnectionURL + + // ClearCache clears all the cache mechanisms the adapter is using. + ClearCache() } // Tx is an interface that enhaces the Database interface with additional diff --git a/internal/sqladapter/database.go b/internal/sqladapter/database.go index 5583dfaf1a3f9aa1b8eeb8407a3cf71471c0cc34..3d2cb99a1ef4b8cce82a8e3448521c624644b810 100644 --- a/internal/sqladapter/database.go +++ b/internal/sqladapter/database.go @@ -7,10 +7,10 @@ import ( "time" "upper.io/db.v2" + "upper.io/db.v2/internal/logger" "upper.io/db.v2/sqlbuilder" "upper.io/db.v2/sqlbuilder/cache" "upper.io/db.v2/sqlbuilder/exql" - "upper.io/db.v2/internal/logger" ) // HasCleanUp @@ -55,6 +55,7 @@ type BaseDatabase interface { Name() string Close() error Ping() error + ClearCache() Collection(string) db.Collection Driver() interface{} @@ -156,6 +157,17 @@ func (d *database) Ping() error { return d.sess.Ping() } +// ClearCache removes all caches. +func (d *database) ClearCache() { + d.collectionMu.Lock() + defer d.collectionMu.Unlock() + d.cachedCollections.Clear() + d.cachedStatements.Clear() + if d.template != nil { + d.template.Cache.Clear() + } +} + // Close terminates the current database session func (d *database) Close() error { defer func() { @@ -168,6 +180,7 @@ func (d *database) Close() error { if d.Tx() != nil && !d.Tx().Committed() { d.Tx().Rollback() } + d.cachedCollections.Clear() d.cachedStatements.Clear() // Closes prepared statements as well. if cleaner, ok := d.PartialDatabase.(HasCleanUp); ok { cleaner.CleanUp() diff --git a/mongo/collection.go b/mongo/collection.go index 7dfc6c5374f85095e47eac1fd1fce4eb9d102dbb..b2ee28b8be8ed4e2335393cc2243d4d265ce5f56 100644 --- a/mongo/collection.go +++ b/mongo/collection.go @@ -235,15 +235,6 @@ func (col *Collection) Insert(item interface{}) (interface{}, error) { } } - // And other interfaces? - if _, ok := id.(bson.ObjectId); ok { - if setter, ok := item.(ObjectIdIDSetter); ok { - if err := setter.SetID(id.(bson.ObjectId)); err != nil { - return nil, err - } - } - } - return id, nil } diff --git a/mongo/database.go b/mongo/database.go index b5c31ca2eb15ca99bfe371c707f088e882a6a123..42c66f9edea09fb4f91c6e22fa6db9d977f7f640 100644 --- a/mongo/database.go +++ b/mongo/database.go @@ -100,6 +100,12 @@ func (s *Source) Ping() error { return s.session.Ping() } +func (s *Source) ClearCache() { + s.collectionsMu.Lock() + defer s.collectionsMu.Unlock() + s.collections = make(map[string]*Collection) +} + // Driver returns the underlying *mgo.Session instance. func (s *Source) Driver() interface{} { return s.session diff --git a/mongo/database_test.go b/mongo/database_test.go index b6204a0b46790492cc6aa58abcfc725eaf39d1fd..3a51d315875625cb1541ad5a5c90212c80e31bdd 100644 --- a/mongo/database_test.go +++ b/mongo/database_test.go @@ -23,7 +23,6 @@ package mongo import ( - "errors" "math/rand" "os" "reflect" @@ -71,36 +70,6 @@ type testValuesStruct struct { Time time.Duration `bson:"_time"` } -type artistWithObjectIdKey struct { - id bson.ObjectId - Name string `db:"name"` -} - -func (artist *artistWithObjectIdKey) SetID(id bson.ObjectId) error { - artist.id = id - return nil -} - -type itemWithKey struct { - ID bson.ObjectId `bson:"-"` - SomeVal string `bson:"some_val"` -} - -func (item itemWithKey) Constraint() db.Cond { - cond := db.Cond{ - "_id": item.ID, - } - return cond -} - -func (item *itemWithKey) SetID(keys map[string]interface{}) error { - if len(keys) == 1 { - item.ID = keys["_id"].(bson.ObjectId) - return nil - } - return errors.New(`Expecting exactly two keys.`) -} - var testValues testValuesStruct func init() { @@ -331,19 +300,6 @@ func TestInsert(t *testing.T) { t.Fatalf("Expecting a valid bson.ObjectId.") } - // Attempt to append and update a private key - itemStruct3 := artistWithObjectIdKey{ - Name: "Janus", - } - - if _, err = artist.Insert(&itemStruct3); err != nil { - t.Fatal(err) - } - - if itemStruct3.id.Valid() == false { - t.Fatalf("Expecting an ID.") - } - var total uint64 // Counting elements, must be exactly 6 elements. @@ -351,10 +307,9 @@ func TestInsert(t *testing.T) { t.Fatal(err) } - if total != 6 { - t.Fatalf("Expecting exactly 6 rows.") + if total != 5 { + t.Fatalf("Expecting exactly 5 rows.") } - } // This test tries to use an empty filter and count how many elements were @@ -769,63 +724,6 @@ func TestDelete(t *testing.T) { } } -// MongoDB: Does not support schemas so it can't has composite keys. We're -// testing db.Constrainer and db.IDSetter interface. -func TestSetterAndConstrainer(t *testing.T) { - var err error - var id interface{} - var sess db.Database - var compositeKeys db.Collection - - if sess, err = db.Open(Adapter, settings); err != nil { - t.Fatal(err) - } - - defer sess.Close() - - compositeKeys = sess.Collection("composite_keys") - - //n := rand.Intn(100000) - - item := itemWithKey{ - // "ABCDEF", - // strconv.Itoa(n), - SomeVal: "Some value", - } - - if id, err = compositeKeys.Insert(&item); err != nil { - t.Fatal(err) - } - - // ids := id.([]interface{}) - - // if ids[0].(string) != item.Code { - // t.Fatal(`Keys must match.`) - // } - // - // if ids[1].(string) != item.UserID { - // t.Fatal(`Keys must match.`) - // } - - // Using constraint interface. - res := compositeKeys.Find(itemWithKey{ID: id.(bson.ObjectId)}) - - var item2 itemWithKey - - if item2.SomeVal == item.SomeVal { - t.Fatal(`Values must be different before query.`) - } - - if err := res.One(&item2); err != nil { - t.Fatal(err) - } - - if item2.SomeVal != item.SomeVal { - t.Fatal(`Values must be equal after query.`) - } - -} - // This test tries to add many different datatypes to a single row in a // collection, then it tries to get the stored datatypes and check if the // stored and the original values match. diff --git a/mongo/id.go b/mongo/id.go deleted file mode 100644 index e1fce2800c7d6c8435689693ce3ef076b2243e43..0000000000000000000000000000000000000000 --- a/mongo/id.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2012-present The upper.io/db authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -package mongo - -import ( - "gopkg.in/mgo.v2/bson" -) - -// ObjectIdIDSetter implements a common pattern for setting IDs of type -// ObjectId. -type ObjectIdIDSetter interface { - SetID(bson.ObjectId) error -}