mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 03:14:40 +03:00
UBERF-8540: Allow derived operations with apply (#7044)
This commit is contained in:
parent
470861ed09
commit
e11a0a87cb
@ -399,6 +399,18 @@ export const notificationOperation: MigrateOperation = {
|
||||
func: async (client: MigrationClient): Promise<void> => {
|
||||
await client.update(DOMAIN_DOC_NOTIFY, { '%hash%': { $exists: true } }, { $set: { '%hash%': null } })
|
||||
}
|
||||
},
|
||||
{
|
||||
state: 'remove-update-txes-docnotify-ctx',
|
||||
func: async (client) => {
|
||||
await client.deleteMany(DOMAIN_TX, {
|
||||
_class: core.class.TxUpdateDoc,
|
||||
objectClass: notification.class.DocNotifyContext,
|
||||
'operations.lastViewedTimestamp': {
|
||||
$exists: true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
|
@ -313,8 +313,8 @@ export class TxOperations implements Omit<Client, 'notify'> {
|
||||
return this.removeDoc(doc._class, doc.space, doc._id)
|
||||
}
|
||||
|
||||
apply (scope?: string, measure?: string): ApplyOperations {
|
||||
return new ApplyOperations(this, scope, measure, this.isDerived)
|
||||
apply (scope?: string, measure?: string, derived?: boolean): ApplyOperations {
|
||||
return new ApplyOperations(this, scope, measure, derived ?? this.isDerived)
|
||||
}
|
||||
|
||||
async diffUpdate<T extends Doc = Doc>(
|
||||
|
@ -85,6 +85,8 @@ export interface LowLevelStorage {
|
||||
|
||||
rawUpdate: <T extends Doc>(domain: Domain, query: DocumentQuery<T>, operations: DocumentUpdate<T>) => Promise<void>
|
||||
|
||||
rawDeleteMany: <T extends Doc>(domain: Domain, query: DocumentQuery<T>) => Promise<void>
|
||||
|
||||
// Traverse documents
|
||||
traverse: <T extends Doc>(
|
||||
domain: Domain,
|
||||
|
@ -760,7 +760,7 @@
|
||||
|
||||
if (unViewed.length === 0) {
|
||||
forceRead = true
|
||||
const op = client.apply(undefined, 'chunter.forceReadContext')
|
||||
const op = client.apply(undefined, 'chunter.forceReadContext', true)
|
||||
await inboxClient.readDoc(op, object._id)
|
||||
await op.commit()
|
||||
}
|
||||
|
@ -419,7 +419,7 @@
|
||||
|
||||
if (unViewed.length === 0) {
|
||||
forceRead = true
|
||||
const op = client.apply(undefined, 'chunter.forceReadContext')
|
||||
const op = client.apply(undefined, 'chunter.forceReadContext', true)
|
||||
await inboxClient.readDoc(op, object._id)
|
||||
await op.commit()
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ export async function hideActivityChannels (contexts: DocNotifyContext[]): Promi
|
||||
export async function readActivityChannels (contexts: DocNotifyContext[]): Promise<void> {
|
||||
const client = InboxNotificationsClientImpl.getClient()
|
||||
const notificationsByContext = get(client.inboxNotificationsByContext)
|
||||
const ops = getClient().apply(undefined, 'readActivityChannels')
|
||||
const ops = getClient().apply(undefined, 'readActivityChannels', true)
|
||||
|
||||
try {
|
||||
for (const context of contexts) {
|
||||
|
@ -235,7 +235,7 @@ export class InboxNotificationsClientImpl implements InboxNotificationsClient {
|
||||
}
|
||||
|
||||
async archiveAllNotifications (): Promise<void> {
|
||||
const ops = getClient().apply(undefined, 'archiveAllNotifications')
|
||||
const ops = getClient().apply(undefined, 'archiveAllNotifications', true)
|
||||
|
||||
try {
|
||||
const inboxNotifications = await ops.findAll(
|
||||
@ -260,7 +260,7 @@ export class InboxNotificationsClientImpl implements InboxNotificationsClient {
|
||||
}
|
||||
|
||||
async readAllNotifications (): Promise<void> {
|
||||
const ops = getClient().apply(undefined, 'readAllNotifications')
|
||||
const ops = getClient().apply(undefined, 'readAllNotifications', true)
|
||||
|
||||
try {
|
||||
const inboxNotifications = await ops.findAll(
|
||||
@ -285,7 +285,7 @@ export class InboxNotificationsClientImpl implements InboxNotificationsClient {
|
||||
}
|
||||
|
||||
async unreadAllNotifications (): Promise<void> {
|
||||
const ops = getClient().apply(undefined, 'unreadAllNotifications')
|
||||
const ops = getClient().apply(undefined, 'unreadAllNotifications', true)
|
||||
|
||||
try {
|
||||
const inboxNotifications = await ops.findAll(
|
||||
|
@ -128,7 +128,7 @@ export async function readNotifyContext (doc: DocNotifyContext): Promise<void> {
|
||||
const inboxClient = InboxNotificationsClientImpl.getClient()
|
||||
const inboxNotifications = get(inboxClient.inboxNotificationsByContext).get(doc._id) ?? []
|
||||
|
||||
const ops = getClient().apply(undefined, 'readNotifyContext')
|
||||
const ops = getClient().apply(undefined, 'readNotifyContext', true)
|
||||
try {
|
||||
await inboxClient.readNotifications(
|
||||
ops,
|
||||
@ -152,7 +152,7 @@ export async function unReadNotifyContext (doc: DocNotifyContext): Promise<void>
|
||||
return
|
||||
}
|
||||
|
||||
const ops = getClient().apply(undefined, 'unReadNotifyContext')
|
||||
const ops = getClient().apply(undefined, 'unReadNotifyContext', true)
|
||||
|
||||
try {
|
||||
await inboxClient.unreadNotifications(
|
||||
|
@ -13,24 +13,24 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Asset, getResource, translate } from '@hcengineering/platform'
|
||||
import { ComponentExtensions, getClient, reduceCalls } from '@hcengineering/presentation'
|
||||
import {
|
||||
AnySvelteComponent,
|
||||
closePanel,
|
||||
getCurrentLocation,
|
||||
Icon,
|
||||
ModernTab,
|
||||
navigate,
|
||||
languageStore,
|
||||
locationToUrl
|
||||
locationToUrl,
|
||||
ModernTab,
|
||||
navigate
|
||||
} from '@hcengineering/ui'
|
||||
import { ComponentExtensions, getClient, reduceCalls } from '@hcengineering/presentation'
|
||||
import { Asset, getResource, translate } from '@hcengineering/platform'
|
||||
import { WorkbenchTab } from '@hcengineering/workbench'
|
||||
import view from '@hcengineering/view'
|
||||
import { showMenu } from '@hcengineering/view-resources'
|
||||
import { WorkbenchTab } from '@hcengineering/workbench'
|
||||
|
||||
import { closeTab, getTabDataByLocation, getTabLocation, selectTab, tabIdStore, tabsStore } from '../workbench'
|
||||
import workbench from '../plugin'
|
||||
import { closeTab, getTabDataByLocation, getTabLocation, selectTab, tabIdStore, tabsStore } from '../workbench'
|
||||
|
||||
export let tab: WorkbenchTab
|
||||
|
||||
@ -63,7 +63,9 @@
|
||||
iconProps = data.iconProps
|
||||
|
||||
if (tab.name !== name && tab.location === locationToUrl(tabLoc)) {
|
||||
const op = client.apply(undefined, undefined, true)
|
||||
await client.diffUpdate(tab, { name })
|
||||
await op.commit()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,8 @@ export class DummyDbAdapter implements DbAdapter {
|
||||
query: DocumentQuery<T>,
|
||||
operations: DocumentUpdate<T>
|
||||
): Promise<void> {}
|
||||
|
||||
async rawDeleteMany<T extends Doc>(domain: Domain, query: DocumentQuery<T>): Promise<void> {}
|
||||
}
|
||||
|
||||
class InMemoryAdapter extends DummyDbAdapter implements DbAdapter {
|
||||
|
@ -36,8 +36,7 @@ const serverCore = plugin(serverCoreId, {
|
||||
SearchPresenter: '' as Ref<Mixin<SearchPresenter>>
|
||||
},
|
||||
space: {
|
||||
DocIndexState: '' as Ref<Space>,
|
||||
TriggerState: '' as Ref<Space>
|
||||
DocIndexState: '' as Ref<Space>
|
||||
},
|
||||
metadata: {
|
||||
FrontUrl: '' as Metadata<string>,
|
||||
|
@ -142,6 +142,10 @@ class ElasticDataAdapter implements DbAdapter {
|
||||
throw new Error('Method not implemented.')
|
||||
}
|
||||
|
||||
async rawDeleteMany<T extends Doc>(domain: Domain, query: DocumentQuery<T>): Promise<void> {
|
||||
throw new Error('Method not implemented')
|
||||
}
|
||||
|
||||
async clean (ctx: MeasureContext, domain: Domain, docs: Ref<Doc>[]): Promise<void> {
|
||||
const indexExists = await this.client.indices.exists({
|
||||
index: this.indexName
|
||||
|
@ -19,10 +19,10 @@ import {
|
||||
FindOptions,
|
||||
type Doc,
|
||||
type Domain,
|
||||
type Iterator,
|
||||
type MeasureContext,
|
||||
type Ref,
|
||||
type StorageIterator,
|
||||
type Iterator
|
||||
type StorageIterator
|
||||
} from '@hcengineering/core'
|
||||
import { PlatformError, unknownStatus } from '@hcengineering/platform'
|
||||
import type { Middleware, PipelineContext } from '@hcengineering/server-core'
|
||||
@ -47,36 +47,35 @@ export class LowLevelMiddleware extends BaseMiddleware implements Middleware {
|
||||
return adapterManager.getAdapter(domain, false).find(ctx, domain, recheck)
|
||||
},
|
||||
|
||||
async load (ctx: MeasureContext, domain: Domain, docs: Ref<Doc>[]): Promise<Doc[]> {
|
||||
return await adapterManager.getAdapter(domain, false).load(ctx, domain, docs)
|
||||
load (ctx: MeasureContext, domain: Domain, docs: Ref<Doc>[]): Promise<Doc[]> {
|
||||
return adapterManager.getAdapter(domain, false).load(ctx, domain, docs)
|
||||
},
|
||||
|
||||
async upload (ctx: MeasureContext, domain: Domain, docs: Doc[]): Promise<void> {
|
||||
await adapterManager.getAdapter(domain, true).upload(ctx, domain, docs)
|
||||
upload (ctx: MeasureContext, domain: Domain, docs: Doc[]): Promise<void> {
|
||||
return adapterManager.getAdapter(domain, true).upload(ctx, domain, docs)
|
||||
},
|
||||
|
||||
async clean (ctx: MeasureContext, domain: Domain, docs: Ref<Doc>[]): Promise<void> {
|
||||
await adapterManager.getAdapter(domain, true).clean(ctx, domain, docs)
|
||||
},
|
||||
async groupBy<T>(ctx: MeasureContext, domain: Domain, field: string): Promise<Set<T>> {
|
||||
return await adapterManager.getAdapter(domain, false).groupBy(ctx, domain, field)
|
||||
groupBy<T>(ctx: MeasureContext, domain: Domain, field: string): Promise<Set<T>> {
|
||||
return adapterManager.getAdapter(domain, false).groupBy(ctx, domain, field)
|
||||
},
|
||||
async rawFindAll<T extends Doc>(domain: Domain, query: DocumentQuery<T>, options?: FindOptions<T>): Promise<T[]> {
|
||||
return await adapterManager.getAdapter(domain, false).rawFindAll(domain, query, options)
|
||||
rawFindAll<T extends Doc>(domain: Domain, query: DocumentQuery<T>, options?: FindOptions<T>): Promise<T[]> {
|
||||
return adapterManager.getAdapter(domain, false).rawFindAll(domain, query, options)
|
||||
},
|
||||
async rawUpdate<T extends Doc>(
|
||||
domain: Domain,
|
||||
query: DocumentQuery<T>,
|
||||
operations: DocumentUpdate<T>
|
||||
): Promise<void> {
|
||||
await adapterManager.getAdapter(domain, true).rawUpdate(domain, query, operations)
|
||||
rawUpdate<T extends Doc>(domain: Domain, query: DocumentQuery<T>, operations: DocumentUpdate<T>): Promise<void> {
|
||||
return adapterManager.getAdapter(domain, true).rawUpdate(domain, query, operations)
|
||||
},
|
||||
async traverse<T extends Doc>(
|
||||
rawDeleteMany (domain, query) {
|
||||
return adapterManager.getAdapter(domain, true).rawDeleteMany(domain, query)
|
||||
},
|
||||
traverse<T extends Doc>(
|
||||
domain: Domain,
|
||||
query: DocumentQuery<T>,
|
||||
options?: Pick<FindOptions<T>, 'sort' | 'limit' | 'projection'>
|
||||
): Promise<Iterator<T>> {
|
||||
return await adapterManager.getAdapter(domain, false).traverse(domain, query, options)
|
||||
return adapterManager.getAdapter(domain, false).traverse(domain, query, options)
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
@ -262,6 +262,10 @@ abstract class MongoAdapterBase implements DbAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
async rawDeleteMany<T extends Doc>(domain: Domain, query: DocumentQuery<T>): Promise<void> {
|
||||
await this.db.collection(domain).deleteMany(this.translateRawQuery(query))
|
||||
}
|
||||
|
||||
abstract init (): Promise<void>
|
||||
|
||||
collection<TSchema extends Document = Document>(domain: Domain): Collection<TSchema> {
|
||||
|
@ -327,6 +327,13 @@ abstract class PostgresAdapterBase implements DbAdapter {
|
||||
})
|
||||
}
|
||||
|
||||
async rawDeleteMany<T extends Doc>(domain: Domain, query: DocumentQuery<T>): Promise<void> {
|
||||
const translatedQuery = this.buildRawQuery(domain, query)
|
||||
await this.retryTxn(this.client, async (client) => {
|
||||
await client.query(`DELETE FROM ${translateDomain(domain)} WHERE ${translatedQuery}`)
|
||||
})
|
||||
}
|
||||
|
||||
async findAll<T extends Doc>(
|
||||
ctx: MeasureContext<SessionData>,
|
||||
_class: Ref<Class<T>>,
|
||||
|
@ -70,6 +70,8 @@ class StorageBlobAdapter implements DbAdapter {
|
||||
operations: DocumentUpdate<T>
|
||||
): Promise<void> {}
|
||||
|
||||
async rawDeleteMany<T extends Doc>(domain: Domain, query: DocumentQuery<T>): Promise<void> {}
|
||||
|
||||
async findAll<T extends Doc>(
|
||||
ctx: MeasureContext,
|
||||
_class: Ref<Class<T>>,
|
||||
|
@ -96,12 +96,6 @@ export class MigrateClientImpl implements MigrationClient {
|
||||
}
|
||||
|
||||
async deleteMany<T extends Doc>(domain: Domain, query: DocumentQuery<T>): Promise<void> {
|
||||
const ctx = new MeasureMetricsContext('deleteMany', {})
|
||||
const docs = await this.lowLevel.rawFindAll(domain, query)
|
||||
await this.lowLevel.clean(
|
||||
ctx,
|
||||
domain,
|
||||
docs.map((d) => d._id)
|
||||
)
|
||||
await this.lowLevel.rawDeleteMany(domain, query)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user