Skip to content

Commit

Permalink
refactor: row order (#473)
Browse files Browse the repository at this point in the history
* refactor: row order

* fix: sqlite test
  • Loading branch information
tea-artist committed Mar 20, 2024
1 parent a8eac47 commit fd0caa3
Show file tree
Hide file tree
Showing 66 changed files with 851 additions and 496 deletions.
11 changes: 1 addition & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,16 +250,7 @@ Giving non-techy people the ability to create their software sounds exciting. Bu

In essence, Teable isn't just another no-code solution, it's a comprehensive answer to the evolving demands of modern software development, ensuring that everyone, regardless of their technical proficiency, has a platform tailored to their needs.

## 🌟 Star distribution

<a href="https://next.ossinsight.io/widgets/official/analyze-repo-stars-map?repo_id=560299175&activity=stars" target="_blank" style="display: block" align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/analyze-repo-stars-map/thumbnail.png?repo_id=560299175&activity=stars&image_size=auto&color_scheme=dark" width="721" height="auto">
<img alt="Star Geographical Distribution of teableio/teable" src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-map/thumbnail.png?repo_id=560299175&activity=stars&image_size=auto&color_scheme=light" width="721" height="auto">
</picture>
</a>

## :heart: Sponsors
## Sponsors :heart:

If you are enjoying some this project in your company, I'd really appreciate a [sponsorship](https://github.com/sponsors/teableio), a [coffee](https://ko-fi.com/teable) or a dropped star.
That gives me some more time to improve it to the next level.
Expand Down
9 changes: 8 additions & 1 deletion apps/nestjs-backend/src/db-provider/db.provider.interface.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { DriverClient, IAggregationField, IFilter, ISortItem } from '@teable/core';
import type { Prisma } from '@teable/db-main-prisma';
import type { Knex } from 'knex';
import type { IFieldInstance } from '../features/field/model/factory';
import type { SchemaType } from '../features/field/util';
Expand Down Expand Up @@ -29,13 +30,19 @@ export interface IDbProvider {

dropTable(tableName: string): string;

renameColumnName(tableName: string, oldName: string, newName: string): string[];
renameColumn(tableName: string, oldName: string, newName: string): string[];

dropColumn(tableName: string, columnName: string): string[];

// sql response format: { name: string }[], name for columnName.
columnInfo(tableName: string): string;

checkColumnExist(
tableName: string,
columnName: string,
prisma: Prisma.TransactionClient
): Promise<boolean>;

dropColumnAndIndex(tableName: string, columnName: string, indexName: string): string[];

modifyColumnSchema(tableName: string, columnName: string, schemaType: SchemaType): string[];
Expand Down
20 changes: 18 additions & 2 deletions apps/nestjs-backend/src/db-provider/postgres.provider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Logger } from '@nestjs/common';
import type { IAggregationField, IFilter, ISortItem } from '@teable/core';
import { DriverClient } from '@teable/core';
import type { PrismaClient } from '@teable/db-main-prisma';
import type { Knex } from 'knex';
import type { IFieldInstance } from '../features/field/model/factory';
import type { SchemaType } from '../features/field/util';
Expand Down Expand Up @@ -42,11 +43,26 @@ export class PostgresProvider implements IDbProvider {
}

dropTable(tableName: string): string {
return this.knex.raw('DROP TABLE ??', [tableName]).toQuery();
}

async checkColumnExist(
tableName: string,
columnName: string,
prisma: PrismaClient
): Promise<boolean> {
const [schemaName, dbTableName] = this.splitTableName(tableName);
return this.knex.raw('DROP TABLE ??.??', [schemaName, dbTableName]).toQuery();
const sql = this.knex
.raw(
'SELECT EXISTS (SELECT FROM information_schema.columns WHERE table_schema = ? AND table_name = ? AND column_name = ?) AS exists',
[schemaName, dbTableName, columnName]
)
.toQuery();
const res = await prisma.$queryRawUnsafe<{ exists: boolean }[]>(sql);
return res[0].exists;
}

renameColumnName(tableName: string, oldName: string, newName: string): string[] {
renameColumn(tableName: string, oldName: string, newName: string): string[] {
return this.knex.schema
.alterTable(tableName, (table) => {
table.renameColumn(oldName, newName);
Expand Down
13 changes: 12 additions & 1 deletion apps/nestjs-backend/src/db-provider/sqlite.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { Logger } from '@nestjs/common';
import type { IAggregationField, IFilter, ISortItem } from '@teable/core';
import { DriverClient } from '@teable/core';
import type { PrismaClient } from '@teable/db-main-prisma';
import type { Knex } from 'knex';
import type { IFieldInstance } from '../features/field/model/factory';
import type { SchemaType } from '../features/field/util';
Expand Down Expand Up @@ -41,7 +42,17 @@ export class SqliteProvider implements IDbProvider {
return this.knex.raw('DROP TABLE ??', [tableName]).toQuery();
}

renameColumnName(tableName: string, oldName: string, newName: string): string[] {
async checkColumnExist(
tableName: string,
columnName: string,
prisma: PrismaClient
): Promise<boolean> {
const sql = this.columnInfo(tableName);
const columns = await prisma.$queryRawUnsafe<{ name: string }[]>(sql);
return columns.some((column) => column.name === columnName);
}

renameColumn(tableName: string, oldName: string, newName: string): string[] {
return [
this.knex
.raw('ALTER TABLE ?? RENAME COLUMN ?? TO ??', [tableName, oldName, newName])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import { Events } from '../event.enum';
import type { IChangeValue } from '../op-event';
import { OpEvent } from '../op-event';

export type IChangeRecord = Record<
keyof Pick<IRecord, 'fields' | 'recordOrder'>,
Record<string, IChangeValue>
> & {
export type IChangeRecord = Record<keyof Pick<IRecord, 'fields'>, Record<string, IChangeValue>> & {
id: string;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,10 @@ describe('AttachmentsService', () => {
const records: IRecord[] = [
{
id: 'record1',
recordOrder: {},
fields: {},
},
{
id: 'record2',
recordOrder: {},
fields: {
field1: mockAttachmentCellValue,
},
Expand Down Expand Up @@ -129,7 +127,6 @@ describe('AttachmentsService', () => {
oldValue: null,
},
},
recordOrder: {},
},
];

Expand Down Expand Up @@ -176,7 +173,6 @@ describe('AttachmentsService', () => {
oldValue: mockOldAttachmentCellValue.slice(0, 1),
},
},
recordOrder: {},
},
{
id: 'record2',
Expand All @@ -186,7 +182,6 @@ describe('AttachmentsService', () => {
oldValue: mockOldAttachmentCellValue.slice(1),
},
},
recordOrder: {},
},
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
generateBaseId,
generateRecordId,
generateTableId,
generateViewId,
generateWorkflowActionId,
} from '@teable/core';
import { vi } from 'vitest';
Expand Down Expand Up @@ -100,7 +99,6 @@ describe('Create-Record Action Test', () => {
fields: {
fldHrMYez5yIwBdKEiK: 'name: mockName',
},
recordOrder: { [generateViewId()]: 1 },
},
],
total: 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,11 @@ describe('Update-Record Action Test', () => {
])
);

vi.spyOn(recordOpenApiService, 'updateRecordById').mockImplementation(
vi.spyOn(recordOpenApiService, 'updateRecord').mockImplementation(
(tableId, recordId, _updateRecordRo) =>
Promise.resolve({
id: recordId,
fields: { [fieldId]: 'update: mockName' },
recordOrder: { tableId: 1 },
})
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class UpdateRecord extends ActionCore {
let outPut: IActionResponse<unknown>;

await this.recordOpenApiService
.updateRecordById(tableId, recordId, updateData)
.updateRecord(tableId, recordId, updateData)
.then((record) => {
outPut = { data: record, status: ActionResponseStatus.OK };
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export class BaseDuplicateService {
const oldViewId = name.substring(ROW_ORDER_FIELD_PREFIX.length + 1);
const newViewId = old2NewViewIdMap[oldViewId];
if (newViewId) {
const query = this.dbProvider.renameColumnName(
const query = this.dbProvider.renameColumn(
dbTableName,
name,
`${ROW_ORDER_FIELD_PREFIX}_${newViewId}`
Expand Down
2 changes: 1 addition & 1 deletion apps/nestjs-backend/src/features/base/base.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class BaseController {
return await this.baseService.duplicateBase(duplicateBaseRo);
}

@Post('createFromTemplate')
@Post('create-from-template')
@Permissions('base|create')
@ResourceMeta('spaceId', 'body')
@EmitControllerEvent(Events.BASE_CREATE)
Expand Down
2 changes: 1 addition & 1 deletion apps/nestjs-backend/src/features/base/base.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export class BaseService {
orderBy: { order: align },
});
},
updateSingle: async (_, id, data) => {
update: async (_, id, data) => {
await this.prismaService.base.update({
data: { order: data.newOrder },
where: { id },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import type {
ILinkFieldOptions,
IOtOperation,
IRecord,
ITinyRecord,
} from '@teable/core';
import { evaluate, FieldType, isMultiValueLink, RecordOpBuilder, Relationship } from '@teable/core';
import { PrismaService } from '@teable/db-main-prisma';
Expand Down Expand Up @@ -42,12 +41,12 @@ export interface IGraphItem {
}

export interface IRecordMap {
[recordId: string]: ITinyRecord;
[recordId: string]: IRecord;
}

export interface IRecordItem {
record: ITinyRecord;
dependencies?: ITinyRecord[];
record: IRecord;
dependencies?: IRecord[];
}

export interface IRecordData {
Expand Down Expand Up @@ -510,7 +509,7 @@ export class ReferenceService {
field: IFieldInstance,
relationship: Relationship,
lookupField: IFieldInstance,
record: ITinyRecord,
record: IRecord,
lookupValues: unknown
): unknown {
if (field.type !== FieldType.Link && field.type !== FieldType.Rollup) {
Expand Down Expand Up @@ -674,7 +673,6 @@ export class ReferenceService {
lastModifiedTime: (raw.__last_modified_time as Date)?.toISOString(),
createdBy: raw.__created_by as string,
lastModifiedBy: raw.__last_modified_by as string,
recordOrder: {},
};
}

Expand Down Expand Up @@ -846,7 +844,7 @@ export class ReferenceService {
recordItemMap:
recordMap &&
Object.values(recordMap).reduce<Record<string, IRecordItem>>((pre, record) => {
let dependencies: ITinyRecord[] | undefined;
let dependencies: IRecord[] | undefined;
if (relatedItems) {
const options = field.lookupOptions
? field.lookupOptions
Expand Down
6 changes: 3 additions & 3 deletions apps/nestjs-backend/src/features/field/field.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { InjectModel } from 'nest-knexjs';
import { ClsService } from 'nestjs-cls';
import { InjectDbProvider } from '../../db-provider/db.provider';
import { IDbProvider } from '../../db-provider/db.provider.interface';
import type { IAdapterService } from '../../share-db/interface';
import type { IReadonlyAdapterService } from '../../share-db/interface';
import { RawOpType } from '../../share-db/interface';
import type { IClsStore } from '../../types/cls';
import { convertNameToValidCharacter } from '../../utils/name-conversion';
Expand All @@ -31,7 +31,7 @@ import { dbType2knexFormat } from './util';
type IOpContext = ISetFieldPropertyOpContext;

@Injectable()
export class FieldService implements IAdapterService {
export class FieldService implements IReadonlyAdapterService {
private logger = new Logger(FieldService.name);

constructor(
Expand Down Expand Up @@ -160,7 +160,7 @@ export class FieldService implements IAdapterService {
throw new BadRequestException(`Db Field name ${newDbFieldName} already exists in this table`);
}

const alterTableSql = this.dbProvider.renameColumnName(
const alterTableSql = this.dbProvider.renameColumn(
table.dbTableName,
dbFieldName,
newDbFieldName
Expand Down
4 changes: 2 additions & 2 deletions apps/nestjs-backend/src/features/graph/graph.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BadRequestException, Injectable, Logger } from '@nestjs/common';
import type { IFieldRo, ILinkFieldOptions, ITinyRecord, IConvertFieldRo } from '@teable/core';
import type { IFieldRo, ILinkFieldOptions, IRecord, IConvertFieldRo } from '@teable/core';
import { FieldType, Relationship } from '@teable/core';
import { PrismaService } from '@teable/db-main-prisma';
import type {
Expand Down Expand Up @@ -109,7 +109,7 @@ export class GraphService {
fieldMap: IFieldMap,
tableMap: { [dbTableName: string]: { dbTableName: string; name: string } },
selectedCell: { recordId: string; fieldId: string },
dbTableName2recordMap: { [dbTableName: string]: Record<string, ITinyRecord> }
dbTableName2recordMap: { [dbTableName: string]: Record<string, IRecord> }
) {
const nodes: IGraphNode[] = [];
const combos: IGraphCombo[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ export class RecordOpenApiController {

@Permissions('record|update')
@Patch(':recordId')
async updateRecordById(
async updateRecord(
@Param('tableId') tableId: string,
@Param('recordId') recordId: string,
@Body(new ZodValidationPipe(updateRecordRoSchema)) updateRecordRo: IUpdateRecordRo
): Promise<IRecord> {
return await this.recordOpenApiService.updateRecordById(tableId, recordId, updateRecordRo);
return await this.recordOpenApiService.updateRecord(tableId, recordId, updateRecordRo);
}

@Permissions('record|create')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import { Module } from '@nestjs/common';
import { AttachmentsStorageModule } from '../../attachments/attachments-storage.module';
import { FieldCalculateModule } from '../../field/field-calculate/field-calculate.module';
import { ViewOpenApiModule } from '../../view/open-api/view-open-api.module';
import { ViewModule } from '../../view/view.module';
import { RecordCalculateModule } from '../record-calculate/record-calculate.module';
import { RecordModule } from '../record.module';
import { RecordOpenApiController } from './record-open-api.controller';
import { RecordOpenApiService } from './record-open-api.service';

@Module({
imports: [RecordModule, RecordCalculateModule, FieldCalculateModule, AttachmentsStorageModule],
imports: [
RecordModule,
RecordCalculateModule,
FieldCalculateModule,
AttachmentsStorageModule,
ViewModule,
ViewOpenApiModule,
],
controllers: [RecordOpenApiController],
providers: [RecordOpenApiService],
exports: [RecordOpenApiService],
Expand Down

0 comments on commit fd0caa3

Please sign in to comment.