github.com/coincircle/mattermost-server@v4.8.1-0.20180321182714-9d701c704416+incompatible/store/layered_store.go (about)

     1  // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package store
     5  
     6  import (
     7  	"context"
     8  
     9  	l4g "github.com/alecthomas/log4go"
    10  	"github.com/mattermost/mattermost-server/einterfaces"
    11  	"github.com/mattermost/mattermost-server/model"
    12  )
    13  
    14  const (
    15  	ENABLE_EXPERIMENTAL_REDIS = false
    16  )
    17  
    18  type LayeredStoreDatabaseLayer interface {
    19  	LayeredStoreSupplier
    20  	Store
    21  }
    22  
    23  type LayeredStore struct {
    24  	TmpContext      context.Context
    25  	ReactionStore   ReactionStore
    26  	DatabaseLayer   LayeredStoreDatabaseLayer
    27  	LocalCacheLayer *LocalCacheSupplier
    28  	RedisLayer      *RedisSupplier
    29  	LayerChainHead  LayeredStoreSupplier
    30  }
    31  
    32  func NewLayeredStore(db LayeredStoreDatabaseLayer, metrics einterfaces.MetricsInterface, cluster einterfaces.ClusterInterface) Store {
    33  	store := &LayeredStore{
    34  		TmpContext:      context.TODO(),
    35  		DatabaseLayer:   db,
    36  		LocalCacheLayer: NewLocalCacheSupplier(metrics, cluster),
    37  	}
    38  
    39  	store.ReactionStore = &LayeredReactionStore{store}
    40  
    41  	// Setup the chain
    42  	if ENABLE_EXPERIMENTAL_REDIS {
    43  		l4g.Debug("Experimental redis enabled.")
    44  		store.RedisLayer = NewRedisSupplier()
    45  		store.RedisLayer.SetChainNext(store.DatabaseLayer)
    46  		store.LayerChainHead = store.RedisLayer
    47  	} else {
    48  		store.LocalCacheLayer.SetChainNext(store.DatabaseLayer)
    49  		store.LayerChainHead = store.LocalCacheLayer
    50  	}
    51  
    52  	return store
    53  }
    54  
    55  type QueryFunction func(LayeredStoreSupplier) *LayeredStoreSupplierResult
    56  
    57  func (s *LayeredStore) RunQuery(queryFunction QueryFunction) StoreChannel {
    58  	storeChannel := make(StoreChannel)
    59  
    60  	go func() {
    61  		result := queryFunction(s.LayerChainHead)
    62  		storeChannel <- result.StoreResult
    63  	}()
    64  
    65  	return storeChannel
    66  }
    67  
    68  func (s *LayeredStore) Team() TeamStore {
    69  	return s.DatabaseLayer.Team()
    70  }
    71  
    72  func (s *LayeredStore) Channel() ChannelStore {
    73  	return s.DatabaseLayer.Channel()
    74  }
    75  
    76  func (s *LayeredStore) Post() PostStore {
    77  	return s.DatabaseLayer.Post()
    78  }
    79  
    80  func (s *LayeredStore) User() UserStore {
    81  	return s.DatabaseLayer.User()
    82  }
    83  
    84  func (s *LayeredStore) Audit() AuditStore {
    85  	return s.DatabaseLayer.Audit()
    86  }
    87  
    88  func (s *LayeredStore) ClusterDiscovery() ClusterDiscoveryStore {
    89  	return s.DatabaseLayer.ClusterDiscovery()
    90  }
    91  
    92  func (s *LayeredStore) Compliance() ComplianceStore {
    93  	return s.DatabaseLayer.Compliance()
    94  }
    95  
    96  func (s *LayeredStore) Session() SessionStore {
    97  	return s.DatabaseLayer.Session()
    98  }
    99  
   100  func (s *LayeredStore) OAuth() OAuthStore {
   101  	return s.DatabaseLayer.OAuth()
   102  }
   103  
   104  func (s *LayeredStore) System() SystemStore {
   105  	return s.DatabaseLayer.System()
   106  }
   107  
   108  func (s *LayeredStore) Webhook() WebhookStore {
   109  	return s.DatabaseLayer.Webhook()
   110  }
   111  
   112  func (s *LayeredStore) Command() CommandStore {
   113  	return s.DatabaseLayer.Command()
   114  }
   115  
   116  func (s *LayeredStore) CommandWebhook() CommandWebhookStore {
   117  	return s.DatabaseLayer.CommandWebhook()
   118  }
   119  
   120  func (s *LayeredStore) Preference() PreferenceStore {
   121  	return s.DatabaseLayer.Preference()
   122  }
   123  
   124  func (s *LayeredStore) License() LicenseStore {
   125  	return s.DatabaseLayer.License()
   126  }
   127  
   128  func (s *LayeredStore) Token() TokenStore {
   129  	return s.DatabaseLayer.Token()
   130  }
   131  
   132  func (s *LayeredStore) Emoji() EmojiStore {
   133  	return s.DatabaseLayer.Emoji()
   134  }
   135  
   136  func (s *LayeredStore) Status() StatusStore {
   137  	return s.DatabaseLayer.Status()
   138  }
   139  
   140  func (s *LayeredStore) FileInfo() FileInfoStore {
   141  	return s.DatabaseLayer.FileInfo()
   142  }
   143  
   144  func (s *LayeredStore) Reaction() ReactionStore {
   145  	return s.ReactionStore
   146  }
   147  
   148  func (s *LayeredStore) Job() JobStore {
   149  	return s.DatabaseLayer.Job()
   150  }
   151  
   152  func (s *LayeredStore) UserAccessToken() UserAccessTokenStore {
   153  	return s.DatabaseLayer.UserAccessToken()
   154  }
   155  
   156  func (s *LayeredStore) ChannelMemberHistory() ChannelMemberHistoryStore {
   157  	return s.DatabaseLayer.ChannelMemberHistory()
   158  }
   159  
   160  func (s *LayeredStore) Plugin() PluginStore {
   161  	return s.DatabaseLayer.Plugin()
   162  }
   163  
   164  func (s *LayeredStore) MarkSystemRanUnitTests() {
   165  	s.DatabaseLayer.MarkSystemRanUnitTests()
   166  }
   167  
   168  func (s *LayeredStore) Close() {
   169  	s.DatabaseLayer.Close()
   170  }
   171  
   172  func (s *LayeredStore) DropAllTables() {
   173  	s.DatabaseLayer.DropAllTables()
   174  }
   175  
   176  func (s *LayeredStore) TotalMasterDbConnections() int {
   177  	return s.DatabaseLayer.TotalMasterDbConnections()
   178  }
   179  
   180  func (s *LayeredStore) TotalReadDbConnections() int {
   181  	return s.DatabaseLayer.TotalReadDbConnections()
   182  }
   183  
   184  func (s *LayeredStore) TotalSearchDbConnections() int {
   185  	return s.DatabaseLayer.TotalSearchDbConnections()
   186  }
   187  
   188  type LayeredReactionStore struct {
   189  	*LayeredStore
   190  }
   191  
   192  func (s *LayeredReactionStore) Save(reaction *model.Reaction) StoreChannel {
   193  	return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
   194  		return supplier.ReactionSave(s.TmpContext, reaction)
   195  	})
   196  }
   197  
   198  func (s *LayeredReactionStore) Delete(reaction *model.Reaction) StoreChannel {
   199  	return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
   200  		return supplier.ReactionDelete(s.TmpContext, reaction)
   201  	})
   202  }
   203  
   204  func (s *LayeredReactionStore) GetForPost(postId string, allowFromCache bool) StoreChannel {
   205  	return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
   206  		return supplier.ReactionGetForPost(s.TmpContext, postId)
   207  	})
   208  }
   209  
   210  func (s *LayeredReactionStore) DeleteAllWithEmojiName(emojiName string) StoreChannel {
   211  	return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
   212  		return supplier.ReactionDeleteAllWithEmojiName(s.TmpContext, emojiName)
   213  	})
   214  }
   215  
   216  func (s *LayeredReactionStore) PermanentDeleteBatch(endTime int64, limit int64) StoreChannel {
   217  	return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
   218  		return supplier.ReactionPermanentDeleteBatch(s.TmpContext, endTime, limit)
   219  	})
   220  }