mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-21 07:46:06 +08:00
fix(perf): Apply accountId to more queries, always run query plans in dev mode to flag SCANs
This commit is contained in:
parent
f33035cfc3
commit
41a3529f16
|
@ -1,8 +1,8 @@
|
|||
FileFrame = require "./file-frame"
|
||||
FileList = require './file-list'
|
||||
FileSelectionBar = require './file-selection-bar'
|
||||
{ComponentRegistry,
|
||||
WorkspaceStore} = require 'nylas-exports'
|
||||
# FileFrame = require "./file-frame"
|
||||
# FileList = require './file-list'
|
||||
# FileSelectionBar = require './file-selection-bar'
|
||||
# {ComponentRegistry,
|
||||
# WorkspaceStore} = require 'nylas-exports'
|
||||
|
||||
module.exports =
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ Reflux = require 'reflux'
|
|||
Contact,
|
||||
Thread,
|
||||
DatabaseStore,
|
||||
AccountStore,
|
||||
ContactStore} = require 'nylas-exports'
|
||||
_ = require 'underscore'
|
||||
|
||||
|
@ -60,7 +61,9 @@ SearchSuggestionStore = Reflux.createStore
|
|||
return if @_threadQueryInFlight
|
||||
|
||||
@_threadQueryInFlight = true
|
||||
DatabaseStore.findAll(Thread, [Thread.attributes.subject.like(val)])
|
||||
DatabaseStore.findAll(Thread)
|
||||
.where(Thread.attributes.subject.like(val))
|
||||
.where(Thread.attributes.accountId.equal(AccountStore.current().id))
|
||||
.order(Thread.attributes.lastMessageReceivedTimestamp.descending())
|
||||
.limit(4)
|
||||
.then (results) =>
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
_ = require 'underscore'
|
||||
Reflux = require 'reflux'
|
||||
request = require 'request'
|
||||
{Contact, ContactStore, DatabaseStore, FocusedContactsStore} = require 'nylas-exports'
|
||||
{Contact,
|
||||
AccountStore
|
||||
ContactStore,
|
||||
DatabaseStore,
|
||||
FocusedContactsStore} = require 'nylas-exports'
|
||||
|
||||
module.exports =
|
||||
FullContactStore = Reflux.createStore
|
||||
|
@ -22,9 +26,10 @@ FullContactStore = Reflux.createStore
|
|||
# for the contact, we get it anew.
|
||||
_loadFocusedContact: ->
|
||||
contact = FocusedContactsStore.focusedContact()
|
||||
account = AccountStore.current()
|
||||
if contact
|
||||
@_resolvedFocusedContact = contact
|
||||
DatabaseStore.findBy(Contact, email: contact.email).then (contact) =>
|
||||
DatabaseStore.findBy(Contact, {email: contact.email, accountId: account.id}).then (contact) =>
|
||||
@_resolvedFocusedContact = contact
|
||||
if contact and not contact.thirdPartyData?["FullContact"]?
|
||||
@_loadContactDataFromAPI(contact)
|
||||
|
|
|
@ -84,7 +84,10 @@ class ThreadListStore extends NylasStore
|
|||
else
|
||||
throw new Error("Invalid organizationUnit")
|
||||
view = new DatabaseView Thread, {matchers}, (ids) =>
|
||||
DatabaseStore.findAll(Message).where(Message.attributes.threadId.in(ids)).then (messages) ->
|
||||
DatabaseStore.findAll(Message)
|
||||
.where(Message.attributes.threadId.in(ids))
|
||||
.where(Message.attributes.accountId.equal(account.id))
|
||||
.then (messages) ->
|
||||
messagesByThread = {}
|
||||
for id in ids
|
||||
messagesByThread[id] = []
|
||||
|
|
|
@ -3,7 +3,7 @@ Thread = require '../../src/flux/models/thread'
|
|||
FocusedContentStore = require '../../src/flux/stores/focused-content-store'
|
||||
Actions = require '../../src/flux/actions'
|
||||
|
||||
testThread = new Thread(id: '123')
|
||||
testThread = new Thread(id: '123', accountId: 'abc')
|
||||
|
||||
describe "FocusedContentStore", ->
|
||||
describe "onSetFocus", ->
|
||||
|
|
|
@ -30,6 +30,7 @@ describe "MessageStore", ->
|
|||
spyOn(DatabaseStore, 'findAll').andCallFake ->
|
||||
include: -> @
|
||||
waitForAnimations: -> @
|
||||
where: -> @
|
||||
then: (callback) -> callback([testMessage1, testMessage2])
|
||||
|
||||
it "should retrieve the focused thread", ->
|
||||
|
|
|
@ -19,7 +19,7 @@ describe "UnreadCountStore", ->
|
|||
atom.testOrganizationUnit = 'folder'
|
||||
UnreadCountStore._fetchCount()
|
||||
advanceClock()
|
||||
expect(DatabaseStore.findBy).toHaveBeenCalledWith(Folder, {name: 'inbox'})
|
||||
expect(DatabaseStore.findBy).toHaveBeenCalledWith(Folder, {name: 'inbox', accountId: 'test_account_id'})
|
||||
|
||||
[Model, Matchers] = DatabaseStore.count.calls[0].args
|
||||
expect(Model).toBe(Thread)
|
||||
|
@ -33,7 +33,7 @@ describe "UnreadCountStore", ->
|
|||
atom.testOrganizationUnit = 'label'
|
||||
UnreadCountStore._fetchCount()
|
||||
advanceClock()
|
||||
expect(DatabaseStore.findBy).toHaveBeenCalledWith(Label, {name: 'inbox'})
|
||||
expect(DatabaseStore.findBy).toHaveBeenCalledWith(Label, {name: 'inbox', accountId: 'test_account_id'})
|
||||
|
||||
[Model, Matchers] = DatabaseStore.count.calls[0].args
|
||||
expect(Matchers[0].attr.modelKey).toBe('accountId')
|
||||
|
|
|
@ -11,10 +11,6 @@ class Event extends Model
|
|||
modelKey: 'id'
|
||||
jsonKey: 'id'
|
||||
|
||||
'accountId': Attributes.String
|
||||
modelKey: 'accountId'
|
||||
jsonKey: 'accountId'
|
||||
|
||||
'title': Attributes.String
|
||||
modelKey: 'title'
|
||||
jsonKey: 'title'
|
||||
|
|
|
@ -17,7 +17,7 @@ PriorityUICoordinator = require '../../priority-ui-coordinator'
|
|||
generateTempId,
|
||||
isTempId} = require '../models/utils'
|
||||
|
||||
DatabaseVersion = 9
|
||||
DatabaseVersion = 10
|
||||
|
||||
DatabasePhase =
|
||||
Setup: 'setup'
|
||||
|
@ -25,7 +25,8 @@ DatabasePhase =
|
|||
Close: 'close'
|
||||
|
||||
DEBUG_TO_LOG = false
|
||||
DEBUG_QUERY_PLANS = false
|
||||
DEBUG_QUERY_PLANS = atom.inDevMode()
|
||||
DEBUG_MISSING_ACCOUNT_ID = false
|
||||
|
||||
BEGIN_TRANSACTION = 'BEGIN TRANSACTION'
|
||||
COMMIT = 'COMMIT'
|
||||
|
@ -168,6 +169,30 @@ class DatabaseStore extends NylasStore
|
|||
app = require('remote').getGlobal('application')
|
||||
app.rebuildDatabase()
|
||||
|
||||
_prettyConsoleLog: (q) =>
|
||||
q = "color:black |||%c " + q
|
||||
q = q.replace(/`(\w+)`/g, "||| color:purple |||%c$&||| color:black |||%c")
|
||||
|
||||
colorRules =
|
||||
'color:green': ['SELECT', 'INSERT INTO', 'VALUES', 'WHERE', 'FROM', 'JOIN', 'ORDER BY', 'DESC', 'ASC', 'INNER', 'OUTER', 'LIMIT', 'OFFSET', 'IN']
|
||||
'color:red; background-color:#ffdddd;': ['SCAN TABLE']
|
||||
|
||||
for style, keywords of colorRules
|
||||
for keyword in keywords
|
||||
q = q.replace(new RegExp("\\b#{keyword}\\b", 'g'), "||| #{style} |||%c#{keyword}||| color:black |||%c")
|
||||
|
||||
q = q.split('|||')
|
||||
colors = []
|
||||
msg = []
|
||||
for i in [0...q.length]
|
||||
if i % 2 is 0
|
||||
colors.push(q[i])
|
||||
else
|
||||
msg.push(q[i])
|
||||
|
||||
console.log(msg.join(''), colors...)
|
||||
|
||||
|
||||
# Returns a promise that resolves when the query has been completed and
|
||||
# rejects when the query has failed.
|
||||
#
|
||||
|
@ -185,9 +210,13 @@ class DatabaseStore extends NylasStore
|
|||
else
|
||||
fn = 'run'
|
||||
|
||||
if DEBUG_QUERY_PLANS and query.indexOf("SELECT ") is 0
|
||||
if query.indexOf("SELECT ") is 0
|
||||
if DEBUG_MISSING_ACCOUNT_ID and query.indexOf("`account_id`") is -1
|
||||
@_prettyConsoleLog("QUERY does not specify accountId: #{query}")
|
||||
if DEBUG_QUERY_PLANS
|
||||
@_db.all "EXPLAIN QUERY PLAN #{query}", values, (err, results) =>
|
||||
console.log(results.map((row) -> row.detail).join('\n') + " for " + query)
|
||||
str = results.map((row) -> row.detail).join('\n') + " for " + query
|
||||
@_prettyConsoleLog(str) if str.indexOf("SCAN") isnt -1
|
||||
|
||||
# Important: once the user begins a transaction, queries need to run in serial.
|
||||
# This ensures that the subsequent "COMMIT" call actually runs after the other
|
||||
|
|
|
@ -34,7 +34,8 @@ class EventStore extends NylasStore
|
|||
|
||||
constructor: ->
|
||||
@_eventCache = {}
|
||||
@_accountId = null
|
||||
@_accountId = AccountStore.current()?.id
|
||||
|
||||
@listenTo DatabaseStore, @_onDatabaseChanged
|
||||
@listenTo AccountStore, @_onAccountChanged
|
||||
|
||||
|
@ -48,9 +49,10 @@ class EventStore extends NylasStore
|
|||
Actions.queueTask(task)
|
||||
|
||||
__refreshCache: =>
|
||||
return unless @_accountId
|
||||
|
||||
new Promise (resolve, reject) =>
|
||||
DatabaseStore.findAll(Event)
|
||||
.then (events=[]) =>
|
||||
DatabaseStore.findAll(Event, {accountId: @_accountId}).then (events=[]) =>
|
||||
@_eventCache[e.id] = e for e in events
|
||||
@trigger()
|
||||
resolve()
|
||||
|
|
|
@ -140,7 +140,8 @@ class MessageStore extends NylasStore
|
|||
return unless @_thread
|
||||
loadedThreadId = @_thread.id
|
||||
|
||||
query = DatabaseStore.findAll(Message, threadId: loadedThreadId)
|
||||
query = DatabaseStore.findAll(Message)
|
||||
query.where(threadId: loadedThreadId, accountId: @_thread.accountId)
|
||||
query.include(Message.attributes.body)
|
||||
query.then (items) =>
|
||||
localIds = {}
|
||||
|
|
|
@ -58,7 +58,7 @@ UnreadCountStore = Reflux.createStore
|
|||
|
||||
# Note: We can't use the convenience methods on CategoryStore to fetch the
|
||||
# category because it may not have been loaded yet
|
||||
DatabaseStore.findBy(CategoryClass, {name: 'inbox'}).then (category) =>
|
||||
DatabaseStore.findBy(CategoryClass, {name: 'inbox', accountId: account.id}).then (category) =>
|
||||
return unless category
|
||||
|
||||
matchers = [
|
||||
|
|
Loading…
Reference in a new issue