Skip to content

Commit

Permalink
add schema based completions
Browse files Browse the repository at this point in the history
  • Loading branch information
lokesh-couchbase committed May 28, 2024
1 parent 71f21cc commit 1c52f4c
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 17 deletions.
6 changes: 6 additions & 0 deletions language/n1ql.tmLanguage
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,12 @@
</dict>
</array>
</dict>
<dict>
<key>match</key>
<string>\$\w+</string>
<key>name</key>
<string>variable.parameter</string>
</dict>
</array>
</dict>
</dict>
Expand Down
27 changes: 27 additions & 0 deletions src/commands/sqlpp/sqlppCompletions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
CompletionContext
} from "vscode";
import { getAllNamedParameters } from "../../util/namedParameters";
import { CacheService, IBucketCache } from "../../util/cacheService/cacheService";

const sqlppKeywords =
"ADAPTER|ALL|ALTER|ANALYTICS|AND|ANY|APPLY|ARGS|AS|ASC|AT|AUTOGENERATED|BETWEEN|BTREE|BY|CASE|CAST|CLOSED|COLLECTION|COMPACT|COMPACTION|CONNECT|CONNECTED|CORRELATE|CREATE|CROSS|CUBE|CURRENT|DATASET|DATAVERSE|DECLARE|DEFINITION|DELETE|DESC|DISABLE|DISCONNECT|DISTINCT|DIV|DROP|ELEMENT|ELSE|ENABLE|END|ENFORCED|EVERY|EXCEPT|EXCLUDE|EXISTS|EXPLAIN|EXTERNAL|FEED|FILTER|FIRST|FLATTEN|FOLLOWING|FOR|FOREIGN|FROM|FULL|FULLTEXT|FUNCTION|GROUP|GROUPING|GROUPS|HAVING|HINTS|IF|IGNORE|IN|INCLUDE|INDEX|INGESTION|INNER|INSERT|INTERNAL|INTERSECT|INTO|IS|JOIN|KEY|KEYWORD|KNOWN|LAST|LEFT|LET|LETTING|LIKE|LIMIT|LINK|LOAD|MISSING|MOD|NGRAM|NO|NODEGROUP|NOT|NULL|NULLS|OFFSET|ON|OPEN|OR|ORDER|OTHERS|OUTER|OUTPUT|OVER|PARTITION|PATH|POLICY|PRECEDING|PRIMARY|RANGE|RAW|REFERENCES|REFRESH|REPLACE|RESPECT|RETURN|RETURNING|RETURNS|RIGHT|ROLLUP|ROW|ROWS|RTREE|RUN|SATISFIES|SCOPE|SECONDARY|SELECT|SET|SETS|SOME|START|STOP|SYNONYM|TEMPORARY|THEN|TIES|TO|TYPE|UNBOUNDED|UNION ALL|UNION|UNKNOWN|UNNEST|UPDATE|UPSERT|USE|USING|VALUE|VALUED|VIEW|WHEN|WHERE|WITH|WRITE";
Expand Down Expand Up @@ -66,3 +67,29 @@ export const sqlppNamedParametersCompletions = (
// Return the array of CompletionItem objects
return completionItems;
};

export const sqlppSchemaComlpletions = (cacheService: CacheService): CompletionItem[] => {
const allKeywordsSet: Set<string> = new Set();
const allSchemas: Map<string, IBucketCache> = cacheService.getAllBucketsData();

for (const [bucketName,bucketCache] of allSchemas.entries()) {
allKeywordsSet.add(bucketName);
for (const [scopeName, scopeCache] of bucketCache.scopes.entries()) {
allKeywordsSet.add(scopeName);
for (const [collectionName] of scopeCache.collections.entries()) {
allKeywordsSet.add(collectionName);
}
}
}

const completionItems: CompletionItem[] = [];
allKeywordsSet.forEach(
(keyword) => {
const item = new CompletionItem(keyword, CompletionItemKind.Text);
item.insertText = new SnippetString(keyword);
completionItems.push(item);
}
);

return completionItems;
};
15 changes: 14 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ import { newChatHandler } from "./commands/iq/chat/newChatHandler";
import { SecretService } from "./util/secretService";
import { kvTypeFilterDocuments } from "./commands/documents/documentFilters/kvTypeFilterDocuments";
import { fetchNamedParameters } from "./pages/namedParameters/namedParameters";
import { sqlppComlpletions, sqlppNamedParametersCompletions } from "./commands/sqlpp/sqlppCompletions";
import { sqlppComlpletions, sqlppNamedParametersCompletions, sqlppSchemaComlpletions } from "./commands/sqlpp/sqlppCompletions";

export function activate(context: vscode.ExtensionContext) {
Global.setState(context.globalState);
Expand Down Expand Up @@ -537,6 +537,19 @@ export function activate(context: vscode.ExtensionContext) {
return sqlppNamedParametersCompletions(document, position);
}}, '$');

let sqlppSchemaComlpletionsDisposable: vscode.Disposable | undefined = undefined;

CacheService.eventEmitter.on("cacheSuccessful", ()=>{
if(sqlppSchemaComlpletionsDisposable){
sqlppSchemaComlpletionsDisposable.dispose();
}

sqlppSchemaComlpletionsDisposable = vscode.languages.registerCompletionItemProvider("SQL++", {
provideCompletionItems() {
return sqlppSchemaComlpletions(cacheService);
}});
});

subscriptions.push(
vscode.commands.registerCommand(
Commands.getClusterOverview,
Expand Down
38 changes: 22 additions & 16 deletions src/util/cacheService/cacheService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { hasQueryService } from "../common";
import { Global } from "../util";
import { QueryIndex } from "couchbase";
import { QueryResult } from "couchbase";
import { CouchbaseError } from 'couchbase'
import { CouchbaseError } from 'couchbase';
import { EventEmitter } from "events";

export type SchemaCacheType = { [index: string]: any };
export interface ISchemaCache {
Expand Down Expand Up @@ -37,6 +38,7 @@ export interface IBucketCache {
export class CacheService {
private bucketsData: Map<string, IBucketCache> = new Map();
private cacheStatus: boolean = false;
public static eventEmitter = new EventEmitter();

CacheService() { }

Expand Down Expand Up @@ -80,7 +82,7 @@ export class CacheService {
}


public cacheSchemaForCollection = async (connection: IConnection, collection: ICollectionCache, result?: QueryResult<any>) => {
private cacheSchemaForCollection = async (connection: IConnection, collection: ICollectionCache, result?: QueryResult<any>) => {
try {
if (!result) {
const query = "INFER `" + collection.bucketName + "`.`" + collection.scopeName + "`.`" + collection.name + "` WITH {\"sample_size\": 2000}";
Expand All @@ -105,7 +107,7 @@ export class CacheService {
}
};

public async cacheIndexesForCollection(connection: IConnection, collection: ICollectionCache, indexesResult?: QueryIndex[]): Promise<QueryIndex[]> {
private async cacheIndexesForCollection(connection: IConnection, collection: ICollectionCache, indexesResult?: QueryIndex[]): Promise<QueryIndex[]> {
if (!indexesResult) {
indexesResult = await connection?.cluster?.queryIndexes().getAllIndexes(collection.bucketName, { scopeName: collection.scopeName, collectionName: collection.name });
}
Expand All @@ -117,7 +119,7 @@ export class CacheService {
}

// This function focuses on complete caching of schema of each collection which are saved in bucket cache
public cacheIndexesAndSchemaForAllBuckets = async (connection: IConnection) => {
private cacheIndexesAndSchemaForAllBuckets = async (connection: IConnection) => {
for (let [_, bucket] of this.bucketsData) {
for (let [_, scope] of bucket.scopes) {
for (let [_, collection] of scope.collections) {
Expand Down Expand Up @@ -205,7 +207,7 @@ export class CacheService {
} catch (error) {
logger.error("Error while refreshing bucket cache" + error);
}
}
};


// Refreshes the cache by updating bucket and collection cache if timestamps are older than timeouts specified/ force refresh is true
Expand Down Expand Up @@ -250,7 +252,7 @@ export class CacheService {
await this.fullCache(true);
}
}
}
};


// Refreshes the index and schema cache for a single collection if necessary
Expand Down Expand Up @@ -283,9 +285,9 @@ export class CacheService {
}

const collectionTimestamp = new Date(collectionData.timeStamp);
let minsDifference = 0
let minsDifference = 0;
const difference = currentTimestamp.getTime() - collectionTimestamp.getTime();
if (difference != 0) {
if (difference !== 0) {
minsDifference = difference / (1000 * 60);
}

Expand All @@ -295,7 +297,7 @@ export class CacheService {
}
}

}
};

// Refreshes the index cache for a single collection
private refreshCollectionIndexCache = async (connection: IConnection, bucketName: string, scopeName: string, collectionName: string, indexesResult?: QueryIndex[]) => {
Expand All @@ -319,7 +321,7 @@ export class CacheService {
if (hasQueryService(connection.services)) {
const indexes = await this.cacheIndexesForCollection(connection, collectionData, indexesResult);
}
}
};

// Updates the Bucket cache if required
public updateBucketCache = async (bucketName: string, forceRefresh: boolean) => {
Expand All @@ -337,7 +339,7 @@ export class CacheService {
await this.fullCache(true);
}
}
}
};


// Updates the Index cache for a particular collection if required
Expand All @@ -357,7 +359,7 @@ export class CacheService {

}

}
};

// Updates the Schema cache for a particular collection if required
public updateCollectionSchemaCache = async (connection: IConnection, bucketName: string, scopeName: string, collectionName: string, collectionTimeout: number, forceRefresh: boolean, queryResult?: QueryResult<any>) => {
Expand All @@ -375,7 +377,7 @@ export class CacheService {
}

}
}
};

// Updates the Index cache and Schema cache for a particular collection if required
public async updateCollectionSchemaAndIndexCache(connection: IConnection, bucketName: string, scopeName: string, collectionName: string, collectionTimeout: number, forceRefresh: boolean, result?: QueryResult<any>, indexesResult?: QueryIndex[]) {
Expand Down Expand Up @@ -403,9 +405,7 @@ export class CacheService {
Global.state.update(`vscode-couchbase.iq.bucketsCache.${connection.connectionIdentifier}`, "");
this.bucketsData.clear();
await this.fullCache(true);

}

}

public updateBucketsData(bucketName: string, bucket: IBucketCache) {
Expand All @@ -418,9 +418,13 @@ export class CacheService {
return this.bucketsData.get(bucketName);
}

public getAllBucketsData(): Map<string, IBucketCache> {
return this.bucketsData;
}


// This function focuses on caching the scopes and collections data for each bucket
public cacheAllBuckets = async (connection: IConnection) => {
private cacheAllBuckets = async (connection: IConnection) => {
this.bucketsData = new Map(); // Remove any existing cache

try {
Expand Down Expand Up @@ -579,6 +583,7 @@ export class CacheService {

const finalJson = JSON.stringify(serializedData);
Global.state.update(`vscode-couchbase.iq.bucketsCache.${connection.connectionIdentifier}`, finalJson);
CacheService.eventEmitter.emit('cacheSuccessful');
// return vscode.globalState.update(BUCKETS_STATE_KEY, finalJson);
}

Expand Down Expand Up @@ -623,6 +628,7 @@ export class CacheService {
}
}
}
CacheService.eventEmitter.emit('cacheSuccessful');
return true;
}

Expand Down

0 comments on commit 1c52f4c

Please sign in to comment.