-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
database.ts
156 lines (131 loc) · 4.05 KB
/
database.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { ArnFormat, IResource, Lazy, Names, Resource, Stack } from 'aws-cdk-lib/core';
import { Construct } from 'constructs';
import { CfnDatabase } from 'aws-cdk-lib/aws-glue';
export interface IDatabase extends IResource {
/**
* The ARN of the catalog.
*/
readonly catalogArn: string;
/**
* The catalog id of the database (usually, the AWS account id)
*/
readonly catalogId: string;
/**
* The ARN of the database.
*
* @attribute
*/
readonly databaseArn: string;
/**
* The name of the database.
*
* @attribute
*/
readonly databaseName: string;
}
export interface DatabaseProps {
/**
* The name of the database.
*
* @default - generated by CDK.
*/
readonly databaseName?: string;
/**
* The location of the database (for example, an HDFS path).
*
* @default undefined. This field is optional in AWS::Glue::Database DatabaseInput
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-glue-database-databaseinput.html
*/
readonly locationUri?: string;
/**
* A description of the database.
*
* @default - no database description
*/
readonly description?: string;
}
/**
* A Glue database.
*/
export class Database extends Resource implements IDatabase {
public static fromDatabaseArn(scope: Construct, id: string, databaseArn: string): IDatabase {
const stack = Stack.of(scope);
class Import extends Resource implements IDatabase {
public databaseArn = databaseArn;
public databaseName = stack.splitArn(databaseArn, ArnFormat.SLASH_RESOURCE_NAME).resourceName!;
public catalogArn = stack.formatArn({ service: 'glue', resource: 'catalog' });
public catalogId = stack.account;
}
return new Import(scope, id);
}
/**
* ARN of the Glue catalog in which this database is stored.
*/
public readonly catalogArn: string;
/**
* The catalog id of the database (usually, the AWS account id).
*/
public readonly catalogId: string;
/**
* ARN of this database.
*/
public readonly databaseArn: string;
/**
* Name of this database.
*/
public readonly databaseName: string;
/**
* Location URI of this database.
*/
public readonly locationUri?: string;
constructor(scope: Construct, id: string, props: DatabaseProps = {}) {
super(scope, id, {
physicalName: props.databaseName ??
Lazy.string({
produce: () => Names.uniqueResourceName(this, {}).toLowerCase(),
}),
});
if (props.description !== undefined) {
validateDescription(props.description);
}
let databaseInput: CfnDatabase.DatabaseInputProperty = {
name: this.physicalName,
description: props.description,
};
if (props.locationUri !== undefined) {
validateLocationUri(props.locationUri);
this.locationUri = props.locationUri;
databaseInput = {
locationUri: this.locationUri,
...databaseInput,
};
}
this.catalogId = Stack.of(this).account;
const resource = new CfnDatabase(this, 'Resource', {
catalogId: this.catalogId,
databaseInput,
});
// see https://docs.aws.amazon.com/glue/latest/dg/glue-specifying-resource-arns.html#data-catalog-resource-arns
this.databaseName = this.getResourceNameAttribute(resource.ref);
this.databaseArn = this.stack.formatArn({
service: 'glue',
resource: 'database',
resourceName: this.databaseName,
});
// catalogId is implicitly the accountId, which is why we don't pass the catalogId here
this.catalogArn = Stack.of(this).formatArn({
service: 'glue',
resource: 'catalog',
});
}
}
function validateLocationUri(locationUri: string): void {
if (locationUri.length < 1 || locationUri.length > 1024) {
throw new Error(`locationUri length must be (inclusively) between 1 and 1024, got ${locationUri.length}`);
}
}
function validateDescription(description: string): void {
if (description.length > 2048) {
throw new Error(`description length must be less than or equal to 2048, got ${description.length}`);
}
}