Move model (#7185)
Some checks are pending
CI / build (push) Waiting to run
CI / svelte-check (push) Blocked by required conditions
CI / formatting (push) Blocked by required conditions
CI / test (push) Blocked by required conditions
CI / uitest (push) Waiting to run
CI / uitest-pg (push) Waiting to run
CI / uitest-qms (push) Waiting to run
CI / docker-build (push) Blocked by required conditions
CI / dist-build (push) Blocked by required conditions

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2024-11-18 17:44:09 +05:00 committed by GitHub
parent 017353ece3
commit 5353a06b07
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 206 additions and 145 deletions

View File

@ -15,25 +15,26 @@
import { saveCollaborativeDoc } from '@hcengineering/collaboration'
import core, {
type Class,
collaborativeDocParse,
coreId,
DOMAIN_MODEL_TX,
DOMAIN_SPACE,
DOMAIN_STATUS,
DOMAIN_TX,
MeasureMetricsContext,
RateLimiter,
type Ref,
type TxCUD,
collaborativeDocParse,
coreId,
generateId,
makeCollaborativeDoc,
MeasureMetricsContext,
RateLimiter,
type AnyAttribute,
type Class,
type Doc,
type Domain,
type MeasureContext,
type Ref,
type Space,
type Status,
type TxCreateDoc
type TxCreateDoc,
type TxCUD
} from '@hcengineering/core'
import {
createDefaultSpace,
@ -304,6 +305,7 @@ export const coreOperation: MigrateOperation = {
if (txes.length === 0) break
for (const tx of txes) {
processed++
const { _id, ...ops } = (tx as any).tx
await client.update(
DOMAIN_TX,
{ _id: tx._id },
@ -311,7 +313,7 @@ export const coreOperation: MigrateOperation = {
$set: {
attachedTo: tx.objectId,
attachedToClass: tx.objectClass,
...(tx as any).tx
...ops
}
}
)
@ -321,6 +323,18 @@ export const coreOperation: MigrateOperation = {
}
}
}
},
{
state: 'move-model-txes',
func: async (client) => {
await client.move(
DOMAIN_TX,
{
objectSpace: core.space.Model
},
DOMAIN_MODEL_TX
)
}
}
])
},

View File

@ -13,11 +13,11 @@
// limitations under the License.
//
import { type CollaborativeDoc, DOMAIN_TX, MeasureMetricsContext, SortingOrder } from '@hcengineering/core'
import { type DocumentSnapshot, type Document, type Teamspace } from '@hcengineering/document'
import { DOMAIN_MODEL_TX, MeasureMetricsContext, SortingOrder, type CollaborativeDoc } from '@hcengineering/core'
import { type Document, type DocumentSnapshot, type Teamspace } from '@hcengineering/document'
import {
tryMigrate,
migrateSpaceRanks,
tryMigrate,
type MigrateOperation,
type MigrateUpdate,
type MigrationClient,
@ -75,7 +75,7 @@ async function migrateTeamspacesMixins (client: MigrationClient): Promise<void>
const newSpaceTypeMixin = document.mixin.DefaultTeamspaceTypeData
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{
objectClass: core.class.Attribute,
'attributes.attributeOf': oldSpaceTypeMixin

View File

@ -1,9 +1,9 @@
import {
AccountRole,
DOMAIN_TX,
DOMAIN_MODEL_TX,
type Account,
type Ref,
type Space,
type Account,
type TxCreateDoc,
type TxUpdateDoc
} from '@hcengineering/core'
@ -30,13 +30,13 @@ export const guestOperation: MigrateOperation = {
1: AccountRole.Maintainer,
2: AccountRole.Owner
}
const createTxes = await client.find<TxCreateDoc<Account>>(DOMAIN_TX, {
const createTxes = await client.find<TxCreateDoc<Account>>(DOMAIN_MODEL_TX, {
_class: core.class.TxCreateDoc,
'attributes.role': { $in: [0, 1, 2] }
})
for (const tx of createTxes) {
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{
_id: tx._id
},
@ -47,13 +47,13 @@ export const guestOperation: MigrateOperation = {
}
)
}
const updateTxes = await client.find<TxUpdateDoc<Account>>(DOMAIN_TX, {
const updateTxes = await client.find<TxUpdateDoc<Account>>(DOMAIN_MODEL_TX, {
_class: core.class.TxUpdateDoc,
'operations.role': { $in: [0, 1, 2] }
})
for (const tx of updateTxes) {
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{
_id: tx._id
},

View File

@ -13,7 +13,14 @@
// limitations under the License.
//
import { AccountRole, DOMAIN_TX, makeCollaborativeDoc, TxOperations, type Ref, type Status } from '@hcengineering/core'
import {
AccountRole,
DOMAIN_MODEL_TX,
makeCollaborativeDoc,
TxOperations,
type Ref,
type Status
} from '@hcengineering/core'
import { leadId, type Lead } from '@hcengineering/lead'
import {
tryMigrate,
@ -26,7 +33,7 @@ import {
import core, { DOMAIN_SPACE } from '@hcengineering/model-core'
import contact, { DOMAIN_CONTACT } from '@hcengineering/model-contact'
import task, { DOMAIN_TASK, createSequence, migrateDefaultStatusesBase } from '@hcengineering/model-task'
import task, { createSequence, DOMAIN_TASK, migrateDefaultStatusesBase } from '@hcengineering/model-task'
import lead from './plugin'
import { defaultLeadStatuses } from './spaceType'
@ -110,7 +117,7 @@ async function migrateDefaultTypeMixins (client: MigrationClient): Promise<void>
const newTaskTypeMixin = lead.mixin.LeadTypeData
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{
objectClass: core.class.Attribute,
'attributes.attributeOf': oldSpaceTypeMixin

View File

@ -13,6 +13,8 @@
// limitations under the License.
//
import chunter from '@hcengineering/chunter'
import contact, { type PersonSpace } from '@hcengineering/contact'
import core, { DOMAIN_TX, type Class, type Doc, type DocumentQuery, type Ref, type Space } from '@hcengineering/core'
import {
migrateSpace,
@ -28,11 +30,9 @@ import notification, {
type InboxNotification
} from '@hcengineering/notification'
import { DOMAIN_PREFERENCE } from '@hcengineering/preference'
import contact, { type PersonSpace } from '@hcengineering/contact'
import chunter from '@hcengineering/chunter'
import { DOMAIN_DOC_NOTIFY, DOMAIN_NOTIFICATION, DOMAIN_USER_NOTIFY } from './index'
import { DOMAIN_SPACE } from '@hcengineering/model-core'
import { DOMAIN_DOC_NOTIFY, DOMAIN_NOTIFICATION, DOMAIN_USER_NOTIFY } from './index'
export async function removeNotifications (
client: MigrationClient,

View File

@ -15,7 +15,7 @@
import { getCategories } from '@anticrm/skillset'
import core, {
DOMAIN_TX,
DOMAIN_MODEL_TX,
toIdMap,
TxOperations,
type Doc,
@ -149,7 +149,7 @@ async function migrateDefaultTypeMixins (client: MigrationClient): Promise<void>
const newTaskTypeMixin = recruit.mixin.ApplicantTypeData
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{
objectClass: core.class.Attribute,
'attributes.attributeOf': oldSpaceTypeMixin

View File

@ -12,18 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
import core, { DOMAIN_TX, type Ref, type TxCreateDoc } from '@hcengineering/core'
import request, { requestId, type Request } from '@hcengineering/request'
import contact, { type Person, type PersonAccount } from '@hcengineering/contact'
import core, { DOMAIN_MODEL_TX, type Ref, type TxCreateDoc } from '@hcengineering/core'
import {
type MigrateUpdate,
type MigrationDocumentQuery,
tryMigrate,
type MigrateOperation,
type MigrateUpdate,
type MigrationClient,
type MigrationDocumentQuery,
type MigrationUpgradeClient,
type ModelLogger
} from '@hcengineering/model'
import contact, { type Person, type PersonAccount } from '@hcengineering/contact'
import request, { requestId, type Request } from '@hcengineering/request'
import { DOMAIN_REQUEST } from '.'
@ -32,7 +32,7 @@ async function migrateRequestPersonAccounts (client: MigrationClient): Promise<v
const requests = await client.find<Request>(DOMAIN_REQUEST, {
_class: { $in: descendants }
})
const personAccountsCreateTxes = await client.find(DOMAIN_TX, {
const personAccountsCreateTxes = await client.find(DOMAIN_MODEL_TX, {
_class: core.class.TxCreateDoc,
objectClass: contact.class.PersonAccount
})

View File

@ -13,8 +13,6 @@
// limitations under the License.
//
import { mergeIds } from '@hcengineering/platform'
import { surveyId } from '@hcengineering/survey'
import survey from '@hcengineering/survey-resources/src/plugin'
export default mergeIds(surveyId, survey, {})
export default survey

View File

@ -15,6 +15,7 @@
import activity, { type DocUpdateMessage } from '@hcengineering/activity'
import {
DOMAIN_MODEL_TX,
DOMAIN_STATUS,
DOMAIN_TX,
TxOperations,
@ -94,7 +95,7 @@ export async function migrateDefaultStatusesBase<T extends Task> (
// 3. More than one type (one system and one custom) - the tool is running after the WS upgrade.
// Not supported for now. Alternatively - Proceed with (2) scenario for the custom one. Delete it in the end.
const defaultTypes = await client.find<TxCreateDoc<ProjectType>>(DOMAIN_TX, {
const defaultTypes = await client.find<TxCreateDoc<ProjectType>>(DOMAIN_MODEL_TX, {
_class: core.class.TxCreateDoc,
objectId: defaultTypeId,
objectSpace: core.space.Model,
@ -120,7 +121,7 @@ export async function migrateDefaultStatusesBase<T extends Task> (
// and not modified by user
if (defaultType.attributes.tasks.length === 1 && defaultType.attributes.tasks[0] === defaultTaskTypeId) {
const defaultTaskType = (
await client.find<TxCreateDoc<TaskType>>(DOMAIN_TX, {
await client.find<TxCreateDoc<TaskType>>(DOMAIN_MODEL_TX, {
_class: core.class.TxCreateDoc,
objectId: defaultTaskTypeId,
objectSpace: core.space.Model,
@ -132,7 +133,7 @@ export async function migrateDefaultStatusesBase<T extends Task> (
logger.log('Moving the existing default type created by ConfigUser to a system one', '')
logger.log('Moving the existing default task type created by ConfigUser to a system one', '')
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{ _id: defaultTaskType._id },
{
$set: {
@ -142,7 +143,7 @@ export async function migrateDefaultStatusesBase<T extends Task> (
)
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{ _id: defaultType._id },
{
$set: {
@ -172,7 +173,7 @@ export async function migrateDefaultStatusesBase<T extends Task> (
logger.log('Moving the existing default type to a custom one', '')
const newId = defaultType.objectId + '-custom'
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{ _id: defaultType._id },
{
$set: {
@ -182,7 +183,7 @@ export async function migrateDefaultStatusesBase<T extends Task> (
}
)
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{
objectId: defaultType.objectId,
objectSpace: core.space.Model
@ -194,7 +195,7 @@ export async function migrateDefaultStatusesBase<T extends Task> (
}
)
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{
objectId: { $in: defaultType.attributes.tasks },
objectSpace: core.space.Model,
@ -294,7 +295,7 @@ export async function migrateDefaultStatusesBase<T extends Task> (
// 1. Update all update TXes with statuses
// 2. Update all push TXes with statuses
const projectTypeStatusesCreates = await client.find<TxCreateDoc<ProjectType>>(DOMAIN_TX, {
const projectTypeStatusesCreates = await client.find<TxCreateDoc<ProjectType>>(DOMAIN_MODEL_TX, {
_class: core.class.TxCreateDoc,
objectClass: task.class.ProjectType,
objectSpace: core.space.Model,
@ -312,11 +313,11 @@ export async function migrateDefaultStatusesBase<T extends Task> (
}
counter++
await client.update(DOMAIN_TX, { _id: ptsCreate._id }, { $set: { 'attributes.statuses': newUpdateStatuses } })
await client.update(DOMAIN_MODEL_TX, { _id: ptsCreate._id }, { $set: { 'attributes.statuses': newUpdateStatuses } })
}
logger.log('projectTypeStatusesCreates updated: ', counter)
const projectTypeStatusesUpdates = await client.find<TxUpdateDoc<ProjectType>>(DOMAIN_TX, {
const projectTypeStatusesUpdates = await client.find<TxUpdateDoc<ProjectType>>(DOMAIN_MODEL_TX, {
_class: core.class.TxUpdateDoc,
objectId: { $in: projectTypeStatusesCreates.map((sc) => sc.objectId) },
objectClass: task.class.ProjectType,
@ -334,11 +335,11 @@ export async function migrateDefaultStatusesBase<T extends Task> (
}
counter++
await client.update(DOMAIN_TX, { _id: ptsUpdate._id }, { $set: { 'operations.statuses': newUpdateStatuses } })
await client.update(DOMAIN_MODEL_TX, { _id: ptsUpdate._id }, { $set: { 'operations.statuses': newUpdateStatuses } })
}
logger.log('projectTypeStatusesUpdates updated: ', counter)
const projectTypeStatusesPushes = await client.find<TxUpdateDoc<ProjectType>>(DOMAIN_TX, {
const projectTypeStatusesPushes = await client.find<TxUpdateDoc<ProjectType>>(DOMAIN_MODEL_TX, {
_class: core.class.TxUpdateDoc,
objectId: { $in: projectTypeStatusesCreates.map((sc) => sc.objectId) },
objectClass: task.class.ProjectType,
@ -362,7 +363,11 @@ export async function migrateDefaultStatusesBase<T extends Task> (
}
counter++
await client.update(DOMAIN_TX, { _id: ptsUpdate._id }, { $set: { 'operations.$push.statuses': newPushStatus } })
await client.update(
DOMAIN_MODEL_TX,
{ _id: ptsUpdate._id },
{ $set: { 'operations.$push.statuses': newPushStatus } }
)
}
logger.log('projectTypeStatusesPushes updated: ', counter)
@ -370,7 +375,7 @@ export async function migrateDefaultStatusesBase<T extends Task> (
// 1. Update create TX
// 2. Update all update TXes with statuses
const allTaskTypes = await client.find<TxCreateDoc<TaskType>>(DOMAIN_TX, {
const allTaskTypes = await client.find<TxCreateDoc<TaskType>>(DOMAIN_MODEL_TX, {
_class: core.class.TxCreateDoc,
objectClass: taskTypeClass,
'attributes.ofClass': { $in: baseTaskClasses }
@ -387,11 +392,15 @@ export async function migrateDefaultStatusesBase<T extends Task> (
}
counter++
await client.update(DOMAIN_TX, { _id: taskType._id }, { $set: { 'attributes.statuses': newTaskTypeStatuses } })
await client.update(
DOMAIN_MODEL_TX,
{ _id: taskType._id },
{ $set: { 'attributes.statuses': newTaskTypeStatuses } }
)
}
logger.log('allTaskTypes updated: ', counter)
const allTaskTypeStatusesUpdates = await client.find<TxUpdateDoc<TaskType>>(DOMAIN_TX, {
const allTaskTypeStatusesUpdates = await client.find<TxUpdateDoc<TaskType>>(DOMAIN_MODEL_TX, {
_class: core.class.TxUpdateDoc,
objectClass: taskTypeClass,
objectId: { $in: allTaskTypes.map((tt) => tt.objectId) },
@ -413,7 +422,7 @@ export async function migrateDefaultStatusesBase<T extends Task> (
counter++
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{ _id: ttsUpdate._id },
{ $set: { 'operations.statuses': newTaskTypeUpdateStatuses } }
)
@ -545,6 +554,12 @@ export const taskOperation: MigrateOperation = {
{ objectId: { $in: missing }, objectSpace: 'task:space:Statuses' },
{ $set: { objectSpace: core.space.Model } }
)
await client.update(
DOMAIN_MODEL_TX,
{ objectId: { $in: missing }, objectSpace: 'task:space:Statuses' },
{ $set: { objectSpace: core.space.Model } }
)
await client.move(DOMAIN_TX, { objectId: { $in: missing }, objectSpace: core.space.Model }, DOMAIN_MODEL_TX)
}
}
},

View File

@ -13,37 +13,37 @@
// limitations under the License.
//
import activity, { type DocUpdateMessage } from '@hcengineering/activity'
import core, {
AccountRole,
DOMAIN_MODEL_TX,
DOMAIN_STATUS,
type Ref,
type Status,
type TxCreateDoc,
TxOperations,
generateId,
toIdMap,
DOMAIN_TX,
type Status,
type Ref,
AccountRole
toIdMap
} from '@hcengineering/core'
import {
type MigrateOperation,
type MigrationClient,
type MigrationUpgradeClient,
type ModelLogger,
createOrUpdate,
tryMigrate,
tryUpgrade,
type MigrateOperation,
type MigrationClient,
type MigrationUpgradeClient
tryUpgrade
} from '@hcengineering/model'
import { DOMAIN_SPACE } from '@hcengineering/model-core'
import activity, { type DocUpdateMessage } from '@hcengineering/activity'
import { DOMAIN_ACTIVITY } from '@hcengineering/model-activity'
import { DOMAIN_SPACE } from '@hcengineering/model-core'
import { DOMAIN_TASK, migrateDefaultStatusesBase } from '@hcengineering/model-task'
import tags from '@hcengineering/tags'
import task from '@hcengineering/task'
import { type IssueStatus, TimeReportDayType, trackerId, type Issue, type Project } from '@hcengineering/tracker'
import { type Issue, type IssueStatus, type Project, TimeReportDayType, trackerId } from '@hcengineering/tracker'
import tracker from './plugin'
import contact from '@hcengineering/model-contact'
import { classicIssueTaskStatuses } from '.'
import tracker from './plugin'
async function createDefaultProject (tx: TxOperations): Promise<void> {
const current = await tx.findOne(tracker.class.Project, {
@ -280,7 +280,7 @@ async function migrateStatusesToModel (client: MigrationClient): Promise<void> {
modifiedBy
}
await client.create(DOMAIN_TX, tx)
await client.create(DOMAIN_MODEL_TX, tx)
}
}
@ -291,7 +291,7 @@ async function migrateDefaultTypeMixins (client: MigrationClient): Promise<void>
const newTaskTypeMixin = tracker.mixin.IssueTypeData
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{
objectClass: core.class.Attribute,
'attributes.attributeOf': oldSpaceTypeMixin
@ -350,7 +350,7 @@ async function migrateDefaultProjectOwners (client: MigrationClient): Promise<vo
async function migrateIssueStatuses (client: MigrationClient): Promise<void> {
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{
objectClass: task.class.TaskType,
'attributes.ofClass': tracker.class.Issue,
@ -363,7 +363,7 @@ async function migrateIssueStatuses (client: MigrationClient): Promise<void> {
}
)
await client.update(
DOMAIN_TX,
DOMAIN_MODEL_TX,
{
objectClass: core.class.Status,
'attributes.ofAttribute': tracker.attribute.IssueStatus

View File

@ -326,6 +326,11 @@ export interface TypeAny<AnyComponent = any> extends Type<any> {
*/
export const DOMAIN_MODEL = 'model' as Domain
/**
* @public
*/
export const DOMAIN_MODEL_TX = 'model_tx' as Domain
/**
* @public
*/

View File

@ -11,7 +11,6 @@ import core, {
type Account,
type AccountClient,
type Client,
type MeasureContext,
type MeasureMetricsContext,
type Version
} from '@hcengineering/core'
@ -36,7 +35,7 @@ import {
setMetadataLocalStorage,
themeStore
} from '@hcengineering/ui'
import { writable, get } from 'svelte/store'
import { get, writable } from 'svelte/store'
import plugin from './plugin'
import { workspaceCreating } from './utils'
@ -304,10 +303,7 @@ export async function connect (title: string): Promise<Client | undefined> {
_client = newClient
console.log('logging in as', email)
let me: Account | undefined = await ctx.with('get-account', {}, async () => await newClient.getAccount())
if (me === undefined) {
me = await createEmployee(ctx, ws, me, newClient)
}
const me: Account | undefined = await ctx.with('get-account', {}, async () => await newClient.getAccount())
if (me !== undefined) {
Analytics.setUser(me.email)
Analytics.setTag('workspace', ws)
@ -374,28 +370,6 @@ export async function connect (title: string): Promise<Client | undefined> {
return newClient
}
async function createEmployee (
ctx: MeasureContext,
ws: string,
me: Account,
newClient: AccountClient
): Promise<Account | undefined> {
const createEmployee = await getResource(login.function.CreateEmployee)
await ctx.with('create-missing-employee', {}, async () => {
await createEmployee(ws)
})
for (let i = 0; i < 5; i++) {
me = await ctx.with('get-account', {}, async () => await newClient.getAccount())
if (me !== undefined) {
break
}
await new Promise((resolve) => {
setTimeout(resolve, 100)
})
}
return me
}
function clearMetadata (ws: string): void {
const tokens = fetchMetadataLocalStorage(login.metadata.LoginTokens)
if (tokens !== null) {

View File

@ -29,10 +29,7 @@ fi
./tool.sh create-account user2 -f Kainin -l Dirak -p 1234
./tool.sh create-account user3 -f Cain -l Velasquez -p 1234
./tool.sh create-account user4 -f Armin -l Karmin -p 1234
./tool.sh assign-workspace user1 sanity-ws-qms
./tool.sh assign-workspace user2 sanity-ws-qms
./tool.sh assign-workspace user3 sanity-ws-qms
./tool.sh assign-workspace user4 sanity-ws-qms
# Make user the workspace maintainer
./tool.sh confirm-email user1
./tool.sh confirm-email user2
@ -40,7 +37,6 @@ fi
./tool.sh confirm-email user4
./tool.sh create-account user_qara -f Qara -l Admin -p 1234
./tool.sh assign-workspace user_qara sanity-ws-qms
./tool.sh confirm-email user_qara
./restore-workspace.sh

View File

@ -15,6 +15,7 @@
import core, {
DOMAIN_MODEL,
DOMAIN_MODEL_TX,
DOMAIN_TX,
SortingOrder,
TxProcessor,
@ -1546,6 +1547,7 @@ class MongoTxAdapter extends MongoAdapterBase implements TxAdapter {
async init (): Promise<void> {
await this._db.init(DOMAIN_TX)
await this._db.init(DOMAIN_MODEL_TX)
}
override async tx (ctx: MeasureContext, ...tx: Tx[]): Promise<TxResult[]> {
@ -1554,34 +1556,74 @@ class MongoTxAdapter extends MongoAdapterBase implements TxAdapter {
}
const opName = tx.length === 1 ? 'tx-one' : 'tx'
await addOperation(
ctx,
opName,
{},
async (ctx) => {
await ctx.with(
'insertMany',
{ domain: 'tx' },
async () => {
try {
await this.txCollection().insertMany(
tx.map((it) => translateDoc(it)),
{
ordered: false
}
)
} catch (err: any) {
ctx.error('failed to write tx', { error: err, message: err.message })
}
},
const modelTxes: Tx[] = []
const baseTxes: Tx[] = []
for (const _tx of tx) {
if (_tx.objectSpace === core.space.Model) {
modelTxes.push(_tx)
} else {
baseTxes.push(_tx)
}
}
if (baseTxes.length > 0) {
await addOperation(
ctx,
opName,
{},
async (ctx) => {
await ctx.with(
'insertMany',
{ domain: 'tx' },
async () => {
try {
await this.txCollection().insertMany(
baseTxes.map((it) => translateDoc(it)),
{
ordered: false
}
)
} catch (err: any) {
ctx.error('failed to write tx', { error: err, message: err.message })
}
},
{
count: tx.length
}
)
},
{ domain: 'tx', count: tx.length }
)
{
count: baseTxes.length
}
)
},
{ domain: 'tx', count: baseTxes.length }
)
}
if (modelTxes.length > 0) {
await addOperation(
ctx,
opName,
{},
async (ctx) => {
await ctx.with(
'insertMany',
{ domain: DOMAIN_MODEL_TX },
async () => {
try {
await this.db.collection<Doc>(DOMAIN_MODEL_TX).insertMany(
modelTxes.map((it) => translateDoc(it)),
{
ordered: false
}
)
} catch (err: any) {
ctx.error('failed to write model tx', { error: err, message: err.message })
}
},
{
count: modelTxes.length
}
)
},
{ domain: DOMAIN_MODEL_TX, count: modelTxes.length }
)
}
ctx.withSync('handleEvent', {}, () => {
this.handleEvent(DOMAIN_TX, 'add', tx.length)
})
@ -1598,8 +1640,8 @@ class MongoTxAdapter extends MongoAdapterBase implements TxAdapter {
@withContext('get-model')
async getModel (ctx: MeasureContext): Promise<Tx[]> {
const txCollection = this.db.collection<Tx>(DOMAIN_TX)
const cursor = txCollection.find({ objectSpace: core.space.Model }, { sort: { _id: 1, modifiedOn: 1 } })
const txCollection = this.db.collection<Tx>(DOMAIN_MODEL_TX)
const cursor = txCollection.find({}, { sort: { _id: 1, modifiedOn: 1 } })
const model = await toArray<Tx>(cursor)
// We need to put all core.account.System transactions first
const systemTx: Tx[] = []

View File

@ -1,4 +1,4 @@
import { DOMAIN_DOC_INDEX_STATE, DOMAIN_SPACE, DOMAIN_TX } from '@hcengineering/core'
import { DOMAIN_DOC_INDEX_STATE, DOMAIN_MODEL_TX, DOMAIN_SPACE, DOMAIN_TX } from '@hcengineering/core'
export type DataType = 'bigint' | 'bool' | 'text' | 'text[]'
@ -223,6 +223,7 @@ export function translateDomain (domain: string): string {
export const domainSchemas: Record<string, Schema> = {
[DOMAIN_SPACE]: spaceSchema,
[DOMAIN_TX]: txSchema,
[DOMAIN_MODEL_TX]: txSchema,
[translateDomain('time')]: timeSchema,
[translateDomain('calendar')]: calendarSchema,
[translateDomain('event')]: eventSchema,

View File

@ -22,6 +22,7 @@ import core, {
type DocumentUpdate,
type Domain,
DOMAIN_MODEL,
DOMAIN_MODEL_TX,
DOMAIN_SPACE,
DOMAIN_TX,
type FindOptions,
@ -1573,7 +1574,7 @@ class PostgresAdapter extends PostgresAdapterBase {
class PostgresTxAdapter extends PostgresAdapterBase implements TxAdapter {
async init (domains?: string[], excludeDomains?: string[]): Promise<void> {
const resultDomains = domains ?? [DOMAIN_TX]
const resultDomains = domains ?? [DOMAIN_TX, DOMAIN_MODEL_TX]
await createTables(this.client, resultDomains)
this._helper.domains = new Set(resultDomains as Domain[])
}
@ -1583,7 +1584,21 @@ class PostgresTxAdapter extends PostgresAdapterBase implements TxAdapter {
return []
}
try {
await this.insert(ctx, DOMAIN_TX, tx)
const modelTxes: Tx[] = []
const baseTxes: Tx[] = []
for (const _tx of tx) {
if (_tx.objectSpace === core.space.Model) {
modelTxes.push(_tx)
} else {
baseTxes.push(_tx)
}
}
if (modelTxes.length > 0) {
await this.insert(ctx, DOMAIN_MODEL_TX, modelTxes)
}
if (baseTxes.length > 0) {
await this.insert(ctx, DOMAIN_TX, baseTxes)
}
} catch (err) {
console.error(err)
}
@ -1592,9 +1607,9 @@ class PostgresTxAdapter extends PostgresAdapterBase implements TxAdapter {
async getModel (ctx: MeasureContext): Promise<Tx[]> {
const res = await this
.client`SELECT * FROM ${this.client(translateDomain(DOMAIN_TX))} WHERE "workspaceId" = ${this.workspaceId.name} AND "objectSpace" = ${core.space.Model} ORDER BY _id ASC, "modifiedOn" ASC`
.client`SELECT * FROM ${this.client(translateDomain(DOMAIN_MODEL_TX))} WHERE "workspaceId" = ${this.workspaceId.name} ORDER BY _id ASC, "modifiedOn" ASC`
const model = res.map((p) => parseDoc<Tx>(p as any, DOMAIN_TX))
const model = res.map((p) => parseDoc<Tx>(p as any, DOMAIN_MODEL_TX))
// We need to put all core.account.System transactions first
const systemTx: Tx[] = []
const userTx: Tx[] = []

View File

@ -411,8 +411,7 @@ export function parseDocWithProjection<T extends Doc> (
} else {
;(rest as any)[key] = null
}
}
if (schema[key] !== undefined && schema[key].type === 'bigint') {
} else if (schema[key] !== undefined && schema[key].type === 'bigint') {
;(rest as any)[key] = Number.parseInt((rest as any)[key])
}
}
@ -443,8 +442,7 @@ export function parseDoc<T extends Doc> (doc: DBDoc, domain: string): T {
} else {
;(rest as any)[key] = null
}
}
if (schema[key] !== undefined && schema[key].type === 'bigint') {
} else if (schema[key] !== undefined && schema[key].type === 'bigint') {
;(rest as any)[key] = Number.parseInt((rest as any)[key])
}
}

View File

@ -25,10 +25,6 @@ fi
./tool.sh create-account user2 -f Kainin -l Dirak -p 1234
./tool.sh create-account super -f Super -l User -p 1234
./tool.sh set-user-admin super true
./tool.sh assign-workspace user1 sanity-ws
./tool.sh assign-workspace user2 sanity-ws
./tool.sh set-user-role user1 sanity-ws OWNER
./tool.sh set-user-role user2 sanity-ws OWNER
# Make user the workspace maintainer
./tool.sh confirm-email user1
./tool.sh confirm-email user2