From c0c46e588167806041696d78e45bd1e6448b8953 Mon Sep 17 00:00:00 2001 From: Denis Rosa Date: Mon, 15 Apr 2024 20:59:06 +0200 Subject: [PATCH] bug fixes --- build.gradle.kts | 8 +- .../intellij/database/ActiveCluster.java | 5 + .../intellij/database/DataLoader.java | 43 ++++- .../listener/DependenciesDownloader.java | 12 +- .../intellij/listener/DependenciesUtil.java | 4 +- .../tools/cbmigrate/MigrationDialog.java | 2 +- .../intellij/tools/dialog/ImportDialog.java | 3 +- .../intellij/tree/TreeRightClickListener.java | 16 +- .../tree/cblite/dialog/CBLImportDialog.java | 3 +- .../cblite/sqlppl/SQLPPLiteFileEditor.java | 9 - .../intellij/workbench/QueryExecutor.java | 2 +- .../intellij/database/DataLoaderTest.java | 179 ++++++++++++++++++ 12 files changed, 258 insertions(+), 28 deletions(-) create mode 100644 src/test/java/com/couchbase/intellij/database/DataLoaderTest.java diff --git a/build.gradle.kts b/build.gradle.kts index ded1af45..54198826 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } group = "com.couchbase" -version = "1.0.9" +version = "1.0.10" java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 @@ -24,7 +24,7 @@ dependencies { implementation(files("lib/couchbase-lite-java-ee-3.1.3-7-release.jar")) annotationProcessor("org.projectlombok:lombok:1.18.30") compileOnly("org.projectlombok:lombok:1.18.30") - implementation("com.couchbase.client:java-client:3.4.11") + implementation("com.couchbase.client:java-client:3.6.1") implementation("org.slf4j:slf4j-simple:2.0.7") implementation("org.eclipse.jgit:org.eclipse.jgit:6.5.0.202303070854-r") implementation("com.google.code.gson:gson:2.10.1") @@ -56,6 +56,10 @@ dependencies { implementation("com.vladsch.flexmark:flexmark:0.64.8") implementation("com.vladsch.flexmark:flexmark-ext-tables:0.64.8") implementation("com.vladsch.flexmark:flexmark-html2md-converter:0.64.8") + + testImplementation("org.testcontainers:couchbase:1.19.7") + testImplementation("org.testcontainers:junit-jupiter:1.19.7") + } // Configure Gradle IntelliJ Plugin diff --git a/src/main/java/com/couchbase/intellij/database/ActiveCluster.java b/src/main/java/com/couchbase/intellij/database/ActiveCluster.java index 277cda5a..e1a48e23 100644 --- a/src/main/java/com/couchbase/intellij/database/ActiveCluster.java +++ b/src/main/java/com/couchbase/intellij/database/ActiveCluster.java @@ -421,6 +421,11 @@ public void updateSchema() { Log.debug("updated cluster schema"); } + @VisibleForTesting + public void setCluster(Cluster cluster) { + this.cluster = cluster; + } + @Override public SavedCluster getSavedCluster() { return savedCluster; diff --git a/src/main/java/com/couchbase/intellij/database/DataLoader.java b/src/main/java/com/couchbase/intellij/database/DataLoader.java index fccb7b17..35921e19 100644 --- a/src/main/java/com/couchbase/intellij/database/DataLoader.java +++ b/src/main/java/com/couchbase/intellij/database/DataLoader.java @@ -216,8 +216,14 @@ public static void listDocuments(DefaultMutableTreeNode parentNode, Tree tree, i parentNode.remove(parentNode.getChildCount() - 1); } + + //selects the attribute that needs to be used according to the index + String idxField = getIndexedField(colNode); + if (idxField == null) { + throw new IndexFailureException(null); + } String filter = colNode.getQueryFilter(); - String query = "Select meta(couchbaseAlias).id as cbFileNameId, meta(couchbaseAlias).type as cbMetaType from `" + colNode.getText() + "` as couchbaseAlias WHERE meta(couchbaseAlias).id IS NOT MISSING " + ((filter == null || filter.isEmpty()) ? "" : (" and " + filter)) + (SQLPPQueryUtils.hasOrderBy(filter) ? "" : " order by meta(couchbaseAlias).id ") + (newOffset == 0 ? "" : " OFFSET " + newOffset) + " limit 10"; + String query = "Select meta(couchbaseAlias).id as cbFileNameId, meta(couchbaseAlias).type as cbMetaType from `" + colNode.getText() + "` as couchbaseAlias WHERE " + idxField + " IS NOT MISSING " + ((filter == null || filter.isEmpty()) ? "" : (" and " + filter)) + (SQLPPQueryUtils.hasOrderBy(filter) ? "" : " order by meta(couchbaseAlias).id ") + (newOffset == 0 ? "" : " OFFSET " + newOffset) + " limit 10"; final List results = ActiveCluster.getInstance().get().bucket(colNode.getBucket()).scope(colNode.getScope()).query(query).rowsAsObject(); InferHelper.invalidateInferCacheIfOlder(colNode.getBucket(), colNode.getScope(), colNode.getText(), TimeUnit.MINUTES.toMillis(5)); @@ -277,6 +283,41 @@ public static void listDocuments(DefaultMutableTreeNode parentNode, Tree tree, i } } + public static String getIndexedField(CollectionNodeDescriptor colNode) { + List idxs = ActiveCluster.getInstance().get().bucket(colNode.getBucket()).scope(colNode.getScope()).collection(colNode.getText()).queryIndexes().getAllIndexes(); + String filter = null; + for (QueryIndex idx : idxs) { + if (idx.primary()) { + return "meta(couchbaseAlias).id"; + } else { + AbstractMap.SimpleEntry result = getValidIndexKey(idx.indexKey()); + if (result != null) { + if (!idx.condition().isPresent() && result.getValue()) { + return result.getKey(); + } else { + filter = result.getKey(); + } + } + } + } + return filter; + } + + private static AbstractMap.SimpleEntry getValidIndexKey(JsonArray array) { + for (int i = 0; i < array.size(); i++) { + String key = array.getString(i); + if (!key.contains("(")) { + if (key.endsWith(" DESC") || key.endsWith(" ASC")) { + key = key.replace(" ASC", "").replace(" DESC", "").trim(); + } + key = key.replaceAll("`", ""); + + return new AbstractMap.SimpleEntry<>(key, i == 0); + } + } + return null; + } + private static void loadKVDocuments(DefaultMutableTreeNode parentNode, Tree tree, int newOffset, CollectionNodeDescriptor colNode) throws Exception { List docIds = CouchbaseRestAPI.listKVDocuments(colNode.getBucket(), colNode.getScope(), colNode.getText(), newOffset, 10); diff --git a/src/main/java/com/couchbase/intellij/listener/DependenciesDownloader.java b/src/main/java/com/couchbase/intellij/listener/DependenciesDownloader.java index 794fa7ed..f9bf7e79 100644 --- a/src/main/java/com/couchbase/intellij/listener/DependenciesDownloader.java +++ b/src/main/java/com/couchbase/intellij/listener/DependenciesDownloader.java @@ -88,38 +88,38 @@ public Map getDownloadList(String os) { if (MACOS_64.equals(os)) { map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-x86_64-apple-darwin.zip", TOOL_SHELL, MACOS_64)); - map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.2.0/couchbase-server-tools_7.2.0-macos_x86_64.zip", TOOL_IMPORT_EXPORT, MACOS_64)); + map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-macos_x86_64.zip", TOOL_IMPORT_EXPORT, MACOS_64)); map.put(ALL_TOOLS, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/7.2.0-macos_64.zip", ALL_TOOLS, MACOS_64)); map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_darwin_amd64.zip", CB_MIGRATE, MACOS_64)); } else if (MACOS_ARM.equals(os)) { map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-aarch64-apple-darwin.zip", TOOL_SHELL, MACOS_ARM)); - map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.2.0/couchbase-server-tools_7.2.0-macos_arm64.zip", TOOL_IMPORT_EXPORT, MACOS_ARM)); + map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-macos_arm64.zip", TOOL_IMPORT_EXPORT, MACOS_ARM)); map.put(ALL_TOOLS, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/7.2.0-macos_arm.zip", ALL_TOOLS, MACOS_ARM)); map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_darwin_arm64.zip", CB_MIGRATE, MACOS_ARM)); } else if (WINDOWS_64.equals(os)) { map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-x86_64-pc-windows-msvc.zip", TOOL_SHELL, WINDOWS_64)); - map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.2.0/couchbase-server-tools_7.2.0-windows_amd64.zip", TOOL_IMPORT_EXPORT, WINDOWS_64)); + map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-windows_amd64.zip", TOOL_IMPORT_EXPORT, WINDOWS_64)); map.put(ALL_TOOLS, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/7.2.0-windows_64.zip", ALL_TOOLS, WINDOWS_64)); map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_windows_amd64.zip", CB_MIGRATE, WINDOWS_64)); } else if (WINDOWS_ARM.equals(os)) { map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-x86_64-pc-windows-msvc.zip", TOOL_SHELL, WINDOWS_ARM)); - map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.2.0/couchbase-server-tools_7.2.0-windows_amd64.zip", TOOL_IMPORT_EXPORT, WINDOWS_ARM)); + map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-windows_amd64.zip", TOOL_IMPORT_EXPORT, WINDOWS_ARM)); map.put(ALL_TOOLS, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/7.2.0-windows_64.zip", ALL_TOOLS, WINDOWS_ARM)); map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_windows_amd64.zip", CB_MIGRATE, WINDOWS_ARM)); } else if (LINUX_64.equals(os)) { map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-x86_64-unknown-linux-gnu.tar.gz", TOOL_SHELL, LINUX_64)); - map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.2.0/couchbase-server-tools_7.2.0-linux_x86_64.tar.gz", TOOL_IMPORT_EXPORT, LINUX_64)); + map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-linux_x86_64.tar.gz", TOOL_IMPORT_EXPORT, LINUX_64)); map.put(ALL_TOOLS, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/7.2.0-linux_64.zip", ALL_TOOLS, LINUX_64)); map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_linux_amd64.zip", CB_MIGRATE, LINUX_64)); } else if (LINUX_ARM.equals(os)) { map.put(TOOL_SHELL, getToolSpec("https://github.com/couchbaselabs/couchbase-shell/releases/download/v0.75.1/cbsh-aarch64-unknown-linux-gnu.tar.gz", TOOL_SHELL, LINUX_ARM)); - map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.2.0/couchbase-server-tools_7.2.0-linux_aarch64.tar.gz", TOOL_IMPORT_EXPORT, LINUX_ARM)); + map.put(TOOL_IMPORT_EXPORT, getToolSpec("https://packages.couchbase.com/releases/7.6.0/couchbase-server-tools_7.6.0-linux_aarch64.tar.gz", TOOL_IMPORT_EXPORT, LINUX_ARM)); map.put(CB_MIGRATE, getToolSpec("https://intellij-plugin-dependencies.s3.us-east-2.amazonaws.com/cbmigrate/cbmigrate_0.0.1-beta_linux_arm64.zip", CB_MIGRATE, LINUX_ARM)); } else { diff --git a/src/main/java/com/couchbase/intellij/listener/DependenciesUtil.java b/src/main/java/com/couchbase/intellij/listener/DependenciesUtil.java index 61487b03..948fc658 100644 --- a/src/main/java/com/couchbase/intellij/listener/DependenciesUtil.java +++ b/src/main/java/com/couchbase/intellij/listener/DependenciesUtil.java @@ -23,9 +23,9 @@ public class DependenciesUtil { public static final String TOOLS_VERSION = "7.2"; - public static final String CBMIGRATE_VERSION = "3"; + public static final String CBMIGRATE_VERSION = "4"; public static final String SHELL_VERSION = "1"; - public static final String CBIMPORT_EXPORT_VERSION = "7.2"; + public static final String CBIMPORT_EXPORT_VERSION = "7.6"; public static final String EXPLAIN_VERSION = "1"; public static final String JS_DEPENDENCIES_KEY = "js_dependencies"; diff --git a/src/main/java/com/couchbase/intellij/tools/cbmigrate/MigrationDialog.java b/src/main/java/com/couchbase/intellij/tools/cbmigrate/MigrationDialog.java index 5917caf2..ff0f1509 100644 --- a/src/main/java/com/couchbase/intellij/tools/cbmigrate/MigrationDialog.java +++ b/src/main/java/com/couchbase/intellij/tools/cbmigrate/MigrationDialog.java @@ -371,7 +371,7 @@ private JPanel createTargetPanel() { JPanel targetPanel = new JPanel(new GridBagLayout()); JLabel infoLabel = new JLabel(); - infoLabel.setIcon(IconLoader.getIcon("/assets/icons/information_big.svg", DocumentFilterDialog.class)); + infoLabel.setIcon(IconLoader.getIcon("/assets/icons/information_big.svg", MigrationDialog.class)); infoLabel.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { diff --git a/src/main/java/com/couchbase/intellij/tools/dialog/ImportDialog.java b/src/main/java/com/couchbase/intellij/tools/dialog/ImportDialog.java index f3e7e9b4..ace6e2f2 100644 --- a/src/main/java/com/couchbase/intellij/tools/dialog/ImportDialog.java +++ b/src/main/java/com/couchbase/intellij/tools/dialog/ImportDialog.java @@ -8,7 +8,6 @@ import com.couchbase.intellij.tools.CBImportCommandBuilder; import com.couchbase.intellij.tree.NewEntityCreationDialog; import com.couchbase.intellij.tree.NewEntityCreationDialog.EntityType; -import com.couchbase.intellij.tree.docfilter.DocumentFilterDialog; import com.couchbase.intellij.workbench.Log; import com.intellij.ide.ui.laf.darcula.ui.DarculaTextBorder; import com.intellij.openapi.application.ApplicationManager; @@ -226,7 +225,7 @@ protected JPanel createDatasetPanel() { JLabel infoLabel = new JLabel(); String fontKeywordColor = ColorHelper.getKeywordColor(); - infoLabel.setIcon(IconLoader.getIcon("/assets/icons/information_big.svg", DocumentFilterDialog.class)); + infoLabel.setIcon(IconLoader.getIcon("/assets/icons/information_big.svg", ImportDialog.class)); infoLabel.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { diff --git a/src/main/java/com/couchbase/intellij/tree/TreeRightClickListener.java b/src/main/java/com/couchbase/intellij/tree/TreeRightClickListener.java index db23f073..86f6395a 100644 --- a/src/main/java/com/couchbase/intellij/tree/TreeRightClickListener.java +++ b/src/main/java/com/couchbase/intellij/tree/TreeRightClickListener.java @@ -677,8 +677,20 @@ public void actionPerformed(@NotNull AnActionEvent e) { AnAction menuItem = new AnAction(filter) { @Override public void actionPerformed(@NotNull AnActionEvent e) { - DocumentFilterDialog dialog = new DocumentFilterDialog(tree, clickedNode, col.getBucket(), col.getScope(), col.getText()); - dialog.show(); + + CollectionNodeDescriptor desc = new CollectionNodeDescriptor( + col.getText(), null, col.getBucket(), col.getScope(), null); + String field = DataLoader.getIndexedField(desc); + + if (field != null) { + DocumentFilterDialog dialog = new DocumentFilterDialog(tree, clickedNode, col.getBucket(), col.getScope(), col.getText()); + dialog.show(); + } else { + ApplicationManager.getApplication().invokeLater(() -> Messages.showErrorDialog( + "Filters can only be applied to collections that have at least one index.", + "Document Filters" + )); + } } }; actionGroup.add(menuItem); diff --git a/src/main/java/com/couchbase/intellij/tree/cblite/dialog/CBLImportDialog.java b/src/main/java/com/couchbase/intellij/tree/cblite/dialog/CBLImportDialog.java index 606999fa..81719e80 100644 --- a/src/main/java/com/couchbase/intellij/tree/cblite/dialog/CBLImportDialog.java +++ b/src/main/java/com/couchbase/intellij/tree/cblite/dialog/CBLImportDialog.java @@ -3,7 +3,6 @@ import com.couchbase.client.java.json.JsonArray; import com.couchbase.client.java.json.JsonObject; import com.couchbase.intellij.tree.cblite.ActiveCBLDatabase; -import com.couchbase.intellij.tree.docfilter.DocumentFilterDialog; import com.couchbase.intellij.workbench.Log; import com.couchbase.lite.Collection; import com.couchbase.lite.*; @@ -98,7 +97,7 @@ protected JPanel createSourceTargetPanel() { String fontKeywordColor = ColorHelper.getKeywordColor(); JLabel infoLabel = new JLabel(); - infoLabel.setIcon(IconLoader.getIcon("/assets/icons/information_big.svg", DocumentFilterDialog.class)); + infoLabel.setIcon(IconLoader.getIcon("/assets/icons/information_big.svg", CBLImportDialog.class)); infoLabel.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { diff --git a/src/main/java/com/couchbase/intellij/tree/cblite/sqlppl/SQLPPLiteFileEditor.java b/src/main/java/com/couchbase/intellij/tree/cblite/sqlppl/SQLPPLiteFileEditor.java index 41767257..37c5d70e 100644 --- a/src/main/java/com/couchbase/intellij/tree/cblite/sqlppl/SQLPPLiteFileEditor.java +++ b/src/main/java/com/couchbase/intellij/tree/cblite/sqlppl/SQLPPLiteFileEditor.java @@ -2,7 +2,6 @@ import com.couchbase.intellij.VirtualFileKeys; -import com.couchbase.intellij.database.ActiveCluster; import com.couchbase.intellij.persistence.storage.QueryHistoryStorage; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -26,7 +25,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.border.Border; import java.awt.*; import java.beans.PropertyChangeListener; import java.util.HashMap; @@ -166,13 +164,6 @@ public void actionPerformed(@NotNull AnActionEvent e) { topPanel.add(leftPanel, BorderLayout.WEST); topPanel.add(rightPanel, BorderLayout.EAST); - if (ActiveCluster.getInstance().getColor() != null) { - Border line = BorderFactory.createMatteBorder(0, 0, 1, 0, ActiveCluster.getInstance().getColor()); - Border margin = BorderFactory.createEmptyBorder(0, 0, 1, 0); - Border compound = BorderFactory.createCompoundBorder(margin, line); - topPanel.setBorder(compound); - } - panel.add(topPanel, BorderLayout.NORTH); } diff --git a/src/main/java/com/couchbase/intellij/workbench/QueryExecutor.java b/src/main/java/com/couchbase/intellij/workbench/QueryExecutor.java index b2b51b12..58e1b977 100644 --- a/src/main/java/com/couchbase/intellij/workbench/QueryExecutor.java +++ b/src/main/java/com/couchbase/intellij/workbench/QueryExecutor.java @@ -217,7 +217,7 @@ public static Boolean executeQuery(BlockingQueue queue, QueryType type, if (!SQLPPAnalyzer.isLimited(project, query)) { Integer queryLimit = ActiveCluster.getInstance().getQueryLimit(); if (queryLimit != null) { - query = String.format("SELECT * FROM (%s) as d LIMIT %d", query, queryLimit); + query = String.format("SELECT d.* FROM (%s) as d LIMIT %d", query, queryLimit); autoLimited = true; } } diff --git a/src/test/java/com/couchbase/intellij/database/DataLoaderTest.java b/src/test/java/com/couchbase/intellij/database/DataLoaderTest.java new file mode 100644 index 00000000..c27f8e26 --- /dev/null +++ b/src/test/java/com/couchbase/intellij/database/DataLoaderTest.java @@ -0,0 +1,179 @@ +package com.couchbase.intellij.database; + +import com.couchbase.client.java.Bucket; +import com.couchbase.client.java.Cluster; +import com.couchbase.client.java.Scope; +import com.couchbase.client.java.manager.collection.CollectionSpec; +import com.couchbase.intellij.tree.node.CollectionNodeDescriptor; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.testcontainers.couchbase.BucketDefinition; +import org.testcontainers.couchbase.CouchbaseContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +public class DataLoaderTest { + + private static Cluster cluster; + private static Bucket bucket; + + private static Scope scope; + + private static final String BUCKET_NAME = "testBucket"; + private static final String USERNAME = "Administrator"; + private static final String PASSWORD = "password"; + + private static String noIndexCollection = "noIndexCollection"; + private static String primaryIndexCollection = "primaryIndexCollection"; + + private static String partialAndSecondaryIndexCollection = "partialAndSecondaryIndexCollection"; + + private static String primaryAndSecondaryIndexCollection = "primaryAndSecondaryIndexCollection"; + + private static String secondaryWithFirstInvalidFieldCollection = "secondaryWithFirstInvalidFieldCollection"; + + private static String secondaryWithFirstInvalidFieldCollectionAndAnotherSecondary = "secondaryWithFirstInvalidFieldCollectionAndAnotherSecondary"; + + private static String secondaryWithSingleFirstInvalid = "secondaryWithSingleFirstInvalid"; + + private static String secondaryWithDesc = "secondaryWithDesc"; + + + @Container + public static CouchbaseContainer couchbaseContainer = new CouchbaseContainer("couchbase/server:latest") + .withBucket(new BucketDefinition(BUCKET_NAME)) + .withCredentials(USERNAME, PASSWORD); + + + @BeforeAll + public static void setup() throws Exception { + // Start the container and get the connection string + couchbaseContainer.start(); + + // Connect to the cluster + cluster = Cluster.connect(couchbaseContainer.getConnectionString(), USERNAME, PASSWORD); + bucket = cluster.bucket(BUCKET_NAME); + scope = bucket.defaultScope(); + + ActiveCluster activeCluster = new ActiveCluster(); + activeCluster.setCluster(cluster); + ActiveCluster.setInstance(activeCluster); + + bucket.collections() + .createCollection(CollectionSpec.create(noIndexCollection, scope.name())); + bucket.collections() + .createCollection(CollectionSpec.create(primaryIndexCollection, scope.name())); + bucket.collections() + .createCollection(CollectionSpec.create(primaryAndSecondaryIndexCollection, scope.name())); + bucket.collections() + .createCollection(CollectionSpec.create(partialAndSecondaryIndexCollection, scope.name())); + bucket.collections() + .createCollection(CollectionSpec.create(secondaryWithFirstInvalidFieldCollection, scope.name())); + bucket.collections() + .createCollection(CollectionSpec.create(secondaryWithFirstInvalidFieldCollectionAndAnotherSecondary, scope.name())); + bucket.collections() + .createCollection(CollectionSpec.create(secondaryWithSingleFirstInvalid, scope.name())); + bucket.collections() + .createCollection(CollectionSpec.create(secondaryWithDesc, scope.name())); + + Thread.sleep(2000); + + scope.query("CREATE PRIMARY INDEX ON " + primaryIndexCollection); + + scope.query("CREATE INDEX test2 ON " + primaryAndSecondaryIndexCollection + "(att1,att2)"); + scope.query("CREATE PRIMARY INDEX ON " + primaryAndSecondaryIndexCollection); + scope.query("CREATE INDEX test3 ON " + primaryAndSecondaryIndexCollection + "(att1,att2)"); + + scope.query("CREATE INDEX test4 ON " + partialAndSecondaryIndexCollection + "(att1,att2) where att1 < att2"); + scope.query("CREATE INDEX test5 ON " + partialAndSecondaryIndexCollection + "(att3,att4)"); + scope.query("CREATE INDEX test6 ON " + partialAndSecondaryIndexCollection + "(att5,att6) where att1 > 100"); + + scope.query("CREATE INDEX test7 ON " + secondaryWithFirstInvalidFieldCollection + "((distinct (array (`v`.`day`) for `v` in `schedule` end)),att2)"); + + scope.query("CREATE INDEX test8 ON " + secondaryWithFirstInvalidFieldCollectionAndAnotherSecondary + "((distinct (array (`v`.`day`) for `v` in `schedule` end)),att2)"); + scope.query("CREATE INDEX test9 ON " + secondaryWithFirstInvalidFieldCollectionAndAnotherSecondary + "(att1,att3)"); + + scope.query("CREATE INDEX test10 ON " + secondaryWithSingleFirstInvalid + "((distinct (array (`v`.`day`) for `v` in `schedule` end)))"); + + scope.query("CREATE INDEX test11 ON " + secondaryWithDesc + "(att1 desc)"); + + } + + @AfterAll + public static void tearDown() { + // Disconnect and stop the container + if (cluster != null) { + cluster.disconnect(); + } + couchbaseContainer.stop(); + } + + @Test + public void testNoIndexCollection() { + CollectionNodeDescriptor desc = new CollectionNodeDescriptor( + noIndexCollection, null, bucket.name(), scope.name(), null); + String result = DataLoader.getIndexedField(desc); + Assertions.assertNull(result); + } + + @Test + public void testPrimaryIndexCollection() { + CollectionNodeDescriptor desc = new CollectionNodeDescriptor( + primaryIndexCollection, null, bucket.name(), scope.name(), null); + String result = DataLoader.getIndexedField(desc); + Assertions.assertEquals("meta(couchbaseAlias).id", result); + } + + @Test + public void testPrimaryAndSecondaryIndexCollection() { + CollectionNodeDescriptor desc = new CollectionNodeDescriptor( + primaryAndSecondaryIndexCollection, null, bucket.name(), scope.name(), null); + String result = DataLoader.getIndexedField(desc); + Assertions.assertEquals("meta(couchbaseAlias).id", result); + } + + @Test + public void testPartialAndSecondaryIndexCollection() { + CollectionNodeDescriptor desc = new CollectionNodeDescriptor( + partialAndSecondaryIndexCollection, null, bucket.name(), scope.name(), null); + String result = DataLoader.getIndexedField(desc); + Assertions.assertEquals("att3", result); + } + + @Test + public void testSecondaryWithFirstInvalidFieldCollection() { + CollectionNodeDescriptor desc = new CollectionNodeDescriptor( + secondaryWithFirstInvalidFieldCollection, null, bucket.name(), scope.name(), null); + String result = DataLoader.getIndexedField(desc); + Assertions.assertEquals("att2", result); + } + + @Test + public void testSecondaryWithFirstInvalidFieldCollectionAndAnotherSecondary() { + CollectionNodeDescriptor desc = new CollectionNodeDescriptor( + secondaryWithFirstInvalidFieldCollectionAndAnotherSecondary, null, bucket.name(), scope.name(), null); + String result = DataLoader.getIndexedField(desc); + Assertions.assertEquals("att1", result); + } + + @Test + public void testSecondaryWithSingleFirstInvalid() { + CollectionNodeDescriptor desc = new CollectionNodeDescriptor( + secondaryWithSingleFirstInvalid, null, bucket.name(), scope.name(), null); + String result = DataLoader.getIndexedField(desc); + Assertions.assertNull(result); + } + + @Test + public void testSecondaryWithDesc() { + CollectionNodeDescriptor desc = new CollectionNodeDescriptor( + secondaryWithDesc, null, bucket.name(), scope.name(), null); + String result = DataLoader.getIndexedField(desc); + Assertions.assertEquals("att1", result); + } + + +}