forked from joe-re/sql-language-server
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcreateTableCandidates.ts
More file actions
107 lines (100 loc) · 3.06 KB
/
createTableCandidates.ts
File metadata and controls
107 lines (100 loc) · 3.06 KB
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
import { Table } from '../../database_libs/AbstractClient'
import { Identifier } from '../Identifier'
import { ICONS } from '../CompletionItemUtils'
/**
* Given a table returns all possible ways to refer to it.
* That is by table name only, using the database scope,
* using the catalog and database scopes.
* @param table
* @returns
*/
function getFullyQualifiedTableName(table: Table): string {
if (table.catalog && table.database) {
return table.catalog + '.' + table.database + '.' + table.tableName
}
if (table.database) {
return table.database + '.' + table.tableName
}
return table.tableName
}
export function createCatalogDatabaseAndTableCandidates(
tables: Table[],
lastToken: string,
onFromClause?: boolean
) {
const qualificationLevel = lastToken.split('.').length - 1
const qualifiedEntities = tables.flatMap((table) => {
const results: Identifier[] = []
// When user types without dots (qualificationLevel === 0), always include
// a table name suggestion. This allows typing "act" to match "actor" even
// if the table has a database (e.g., "squeal.actor").
if (qualificationLevel === 0) {
const tableIdentifier = new Identifier(
lastToken,
table.tableName,
'',
ICONS.TABLE,
onFromClause ? 'FROM' : 'OTHERS'
)
results.push(tableIdentifier)
}
// Also add qualified suggestions (catalog/database) based on qualification level
let qualificationNeeded = 0
if (table.catalog) {
qualificationNeeded++
}
if (table.database) {
qualificationNeeded++
}
const qualificationLevelNeeded = qualificationNeeded - qualificationLevel
switch (qualificationLevelNeeded) {
case 0: {
// Only add fully qualified name if we haven't already added just the table name
if (qualificationLevel > 0) {
const tableIdentifier = new Identifier(
lastToken,
getFullyQualifiedTableName(table),
'',
ICONS.TABLE,
onFromClause ? 'FROM' : 'OTHERS'
)
results.push(tableIdentifier)
}
break
}
case 1: {
const qualifiedDatabaseName =
table.catalog && table.database
? table.catalog + '.' + table.database
: table.database
if (qualifiedDatabaseName !== null) {
const databaseIdentifier = new Identifier(
lastToken,
qualifiedDatabaseName,
'',
ICONS.DATABASE,
onFromClause ? 'FROM' : 'OTHERS'
)
results.push(databaseIdentifier)
}
break
}
case 2:
if (table.catalog) {
const catalogIdentifier = new Identifier(
lastToken,
table.catalog,
'',
ICONS.CATALOG,
onFromClause ? 'FROM' : 'OTHERS'
)
results.push(catalogIdentifier)
}
break
}
return results
})
return qualifiedEntities
.filter((item) => item.matchesLastToken())
.map((item) => item.toCompletionItem())
}