Skip to content

Commit feb2570

Browse files
committed
feat: add all defined options to createTable functions
Also deprecate using `profile` and `withProfile` in TableDescription
1 parent 06a955d commit feb2570

File tree

2 files changed

+230
-11
lines changed

2 files changed

+230
-11
lines changed

src/__tests__/create-table.test.ts

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
import Driver from '../driver';
2+
import {destroyDriver, initDriver} from '../test-utils';
3+
import {Column, DescribeTableSettings, TableDescription} from '../table';
4+
import {TypedValues, Types} from '../types';
5+
import Long from 'long';
6+
import {Ydb} from 'ydb-sdk-proto';
7+
8+
const getTableName = () => `table_create_${Math.trunc(100000 * Math.random())}`;
9+
10+
describe('Create table', () => {
11+
let driver: Driver;
12+
let getBaseTableDesc = () => {
13+
const td = new TableDescription()
14+
.withColumn(new Column('id', Types.optional(Types.UINT64)))
15+
.withColumn(new Column('title', Types.optional(Types.UTF8), 'title_time'))
16+
.withColumn(new Column('time', Types.optional(Types.TIMESTAMP), 'title_time'))
17+
.withPrimaryKey('id');
18+
return td;
19+
};
20+
21+
beforeAll(async () => {
22+
driver = await initDriver();
23+
});
24+
25+
afterAll(async () => await destroyDriver(driver));
26+
27+
it('Simple usage with indexes', async () => {
28+
await driver.tableClient.withSession(async (session) => {
29+
const tableName = getTableName();
30+
await session.createTable(tableName, getBaseTableDesc());
31+
32+
const createdTableDescription = await session.describeTable(tableName);
33+
34+
expect(createdTableDescription.primaryKey).toStrictEqual(['id']);
35+
expect(JSON.stringify(createdTableDescription.columns)).toBe(
36+
JSON.stringify([
37+
{name: 'id', type: {optionalType: {item: {typeId: 'UINT64'}}}},
38+
{
39+
name: 'title',
40+
type: {optionalType: {item: {typeId: 'UTF8'}}},
41+
family: 'title_time',
42+
},
43+
{
44+
name: 'time',
45+
type: {optionalType: {item: {typeId: 'TIMESTAMP'}}},
46+
family: 'title_time',
47+
},
48+
]),
49+
);
50+
});
51+
});
52+
53+
it('TTLSettings and uniformPartitions', async () => {
54+
const tableDescription = getBaseTableDesc().withTtl('time', 314);
55+
tableDescription.uniformPartitions = 10;
56+
const tableName = getTableName();
57+
await driver.tableClient.withSession(async (session) => {
58+
await session.createTable(tableName, tableDescription);
59+
const createdTableDescription = await session.describeTable(
60+
tableName,
61+
new DescribeTableSettings().withIncludeTableStats(true),
62+
);
63+
64+
expect(JSON.parse(JSON.stringify(createdTableDescription.ttlSettings))).toStrictEqual({
65+
dateTypeColumn: {
66+
columnName: 'time',
67+
expireAfterSeconds: 314,
68+
},
69+
});
70+
expect(createdTableDescription.tableStats?.partitions).toStrictEqual(
71+
new Long(10, undefined, true),
72+
);
73+
});
74+
});
75+
76+
// somehow YDB normally combines min/max partitions with setted by uniform
77+
// and uses it as initial amount of partitions
78+
it('partitioningSettings', async () => {
79+
const tableDescription = getBaseTableDesc();
80+
tableDescription.partitioningSettings = {
81+
maxPartitionsCount: 2222,
82+
minPartitionsCount: 111,
83+
partitionBy: ['id'],
84+
partitioningByLoad: Ydb.FeatureFlag.Status.ENABLED,
85+
partitioningBySize: Ydb.FeatureFlag.Status.ENABLED,
86+
partitionSizeMb: 1024,
87+
};
88+
tableDescription.uniformPartitions = 50;
89+
tableDescription.attributes = {TEST_MY_ATTR: 'TRRUUUEEEE'};
90+
const tableName = getTableName();
91+
await driver.tableClient.withSession(async (session) => {
92+
await session.createTable(tableName, tableDescription);
93+
const createdTableDescription = await session.describeTable(
94+
tableName,
95+
new DescribeTableSettings().withIncludeTableStats(true),
96+
);
97+
98+
expect(createdTableDescription.attributes).toStrictEqual({TEST_MY_ATTR: 'TRRUUUEEEE'});
99+
expect(
100+
JSON.parse(JSON.stringify(createdTableDescription.partitioningSettings)),
101+
).toStrictEqual({
102+
maxPartitionsCount: '2222',
103+
minPartitionsCount: '111',
104+
partitionSizeMb: '1024',
105+
partitioningByLoad: 'ENABLED',
106+
partitioningBySize: 'ENABLED',
107+
});
108+
expect(createdTableDescription.tableStats?.partitions).toStrictEqual(
109+
new Long(50, undefined, true),
110+
);
111+
});
112+
});
113+
114+
it('columnFamilies', async () => {
115+
const tableDescription = getBaseTableDesc();
116+
tableDescription.columnFamilies = [
117+
{
118+
name: 'title_time',
119+
compression: Ydb.Table.ColumnFamily.Compression.COMPRESSION_LZ4,
120+
// keepInMemory: Ydb.FeatureFlag.Status.ENABLED, // impossible to check for now
121+
data: {media: 'hdd'}, // impossible to check for now
122+
},
123+
];
124+
const tableName = getTableName();
125+
await driver.tableClient.withSession(async (session) => {
126+
await session.createTable(tableName, tableDescription);
127+
const createdTableDescription = await session.describeTable(tableName);
128+
129+
expect(
130+
JSON.parse(JSON.stringify(createdTableDescription.columnFamilies)),
131+
).toStrictEqual([
132+
{compression: 'COMPRESSION_NONE', name: 'default'},
133+
{
134+
compression: 'COMPRESSION_LZ4',
135+
name: 'title_time',
136+
data: {media: 'hdd'},
137+
},
138+
]);
139+
});
140+
});
141+
142+
it('storageSettings, readReplicasSettings and keyBloomFilter', async () => {
143+
const tableDescription = getBaseTableDesc();
144+
// tableDescription.compactionPolicy = 'default'; // impossible to check for now
145+
tableDescription.storageSettings = {
146+
external: {media: 'hdd'},
147+
tabletCommitLog0: {media: 'hdd'},
148+
tabletCommitLog1: {media: 'hdd'},
149+
};
150+
tableDescription.readReplicasSettings = {
151+
perAzReadReplicasCount: 2,
152+
};
153+
tableDescription.keyBloomFilter = Ydb.FeatureFlag.Status.ENABLED;
154+
const tableName = getTableName();
155+
await driver.tableClient.withSession(async (session) => {
156+
await session.createTable(tableName, tableDescription);
157+
158+
const createdTableDescription = await session.describeTable(tableName);
159+
expect(
160+
JSON.parse(JSON.stringify(createdTableDescription.storageSettings)),
161+
).toStrictEqual({
162+
external: {media: 'hdd'},
163+
storeExternalBlobs: 'DISABLED',
164+
tabletCommitLog0: {media: 'hdd'},
165+
tabletCommitLog1: {media: 'hdd'},
166+
});
167+
expect(JSON.stringify(createdTableDescription.readReplicasSettings)).toStrictEqual(
168+
'{"perAzReadReplicasCount":"2"}',
169+
);
170+
expect(createdTableDescription.keyBloomFilter).toStrictEqual(
171+
Ydb.FeatureFlag.Status.ENABLED,
172+
);
173+
});
174+
});
175+
176+
it('partitionAtKeys and readReplicasSettings', async () => {
177+
const tableDescription = getBaseTableDesc();
178+
tableDescription.partitionAtKeys = {
179+
splitPoints: [
180+
TypedValues.tuple(TypedValues.optional(TypedValues.uint64(10))),
181+
TypedValues.tuple(TypedValues.optional(TypedValues.uint64(30))),
182+
TypedValues.tuple(TypedValues.optional(TypedValues.uint64(50))),
183+
TypedValues.tuple(TypedValues.optional(TypedValues.uint64(60))),
184+
TypedValues.tuple(TypedValues.optional(TypedValues.uint64(70))),
185+
TypedValues.tuple(TypedValues.optional(TypedValues.uint64(80))),
186+
TypedValues.tuple(TypedValues.optional(TypedValues.uint64(90))),
187+
],
188+
};
189+
const tableName = getTableName();
190+
await driver.tableClient.withSession(async (session) => {
191+
await session.createTable(tableName, tableDescription);
192+
193+
const createdTableDescription = await session.describeTable(
194+
tableName,
195+
new DescribeTableSettings().withIncludeTableStats(true),
196+
);
197+
expect(createdTableDescription.tableStats?.partitions).toStrictEqual(
198+
new Long(8, undefined, true),
199+
);
200+
});
201+
});
202+
});

src/table.ts

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
StreamEnd,
99
ensureOperationSucceeded,
1010
getOperationPayload,
11-
pessimizable, AsyncResponse
11+
pessimizable,
12+
AsyncResponse,
1213
} from './utils';
1314
import DiscoveryService, {Endpoint} from './discovery';
1415
import {IPoolSettings} from './driver';
@@ -25,7 +26,7 @@ import {
2526
SessionBusy,
2627
MissingValue,
2728
YdbError,
28-
MissingStatus
29+
MissingStatus,
2930
} from './errors';
3031

3132
import TableService = Ydb.Table.V1.TableService;
@@ -360,17 +361,17 @@ export class Session extends EventEmitter implements ICreateSessionResult {
360361

361362
@retryable()
362363
@pessimizable
363-
public async createTable(tablePath: string, description: TableDescription, settings?: CreateTableSettings): Promise<void> {
364-
const {columns, primaryKey, indexes, profile, ttlSettings} = description;
364+
public async createTable(
365+
tablePath: string,
366+
description: TableDescription,
367+
settings?: CreateTableSettings,
368+
): Promise<void> {
365369
const request: Ydb.Table.ICreateTableRequest = {
370+
...description,
366371
sessionId: this.sessionId,
367372
path: `${this.endpoint.database}/${tablePath}`,
368-
columns,
369-
primaryKey,
370-
indexes,
371-
profile,
372-
ttlSettings,
373373
};
374+
374375
if (settings) {
375376
request.operationParams = settings.operationParams;
376377
}
@@ -1170,10 +1171,22 @@ export class TtlSettings implements Ydb.Table.ITtlSettings {
11701171
}
11711172
}
11721173

1173-
export class TableDescription {
1174+
export class TableDescription implements Ydb.Table.ICreateTableRequest {
1175+
/** @deprecated use TableDescription options instead */
11741176
public profile?: TableProfile;
11751177
public indexes: TableIndex[] = [];
11761178
public ttlSettings?: TtlSettings;
1179+
public partitioningSettings?: Ydb.Table.IPartitioningSettings;
1180+
public uniformPartitions?: number;
1181+
public columnFamilies?: Ydb.Table.IColumnFamily[];
1182+
public attributes?: {[k: string]: string};
1183+
public compactionPolicy?: 'default' | 'small_table' | 'log_table';
1184+
public keyBloomFilter?: FeatureFlag;
1185+
public partitionAtKeys?: Ydb.Table.IExplicitPartitions;
1186+
public readReplicasSettings?: Ydb.Table.IReadReplicasSettings;
1187+
public storageSettings?: Ydb.Table.IStorageSettings;
1188+
// path and operationPrams defined in createTable,
1189+
// columns and primaryKey are in constructor
11771190

11781191
constructor(public columns: Column[] = [], public primaryKey: string[] = []) {}
11791192

@@ -1201,6 +1214,7 @@ export class TableDescription {
12011214
return this;
12021215
}
12031216

1217+
/** @deprecated use TableDescription options instead */
12041218
withProfile(profile: TableProfile) {
12051219
this.profile = profile;
12061220
return this;
@@ -1220,9 +1234,12 @@ export class TableDescription {
12201234

12211235
withTtl(columnName: string, expireAfterSeconds: number = 0) {
12221236
this.ttlSettings = new TtlSettings(columnName, expireAfterSeconds);
1223-
12241237
return this;
12251238
}
1239+
1240+
withPartitioningSettings(partitioningSettings: Ydb.Table.IPartitioningSettings) {
1241+
this.partitioningSettings = partitioningSettings;
1242+
}
12261243
}
12271244

12281245
export class AlterTableDescription {

0 commit comments

Comments
 (0)