Skip to content

Commit e860fb2

Browse files
Added support for DQLPart language (#123)
* Added support for DQLPart language The language is a better option than the DQL file name part as it is much easier to disable some parts of the language feature support when the file type is different. * Resolving code review issues * Resolving code review issues * Resolving code review issues
1 parent 783e299 commit e860fb2

19 files changed

+299
-26
lines changed

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,21 @@
2121
- All code style & highlighting settings will be inherited from the DQL language.
2222
- All suitable DQL inspections will be applied to the expression, allowing the user to validate them.
2323
- Code completion and hover documentation are also supported.
24+
- Adding support for the "Partial DQL" file type (with `.dqlpart` extension). This language works similar to
25+
the previous `.partial.dql` files, but allows for an easier separation from the normal DQL file.
26+
- Added a quick fix to migrate from the old `.partial.dql` suffix to the new `.dqlpart` extension.
27+
- Works exactly like a normal DQL file, but allows to use non-starting commands like `filter` or `sort` as the first
28+
statement in the query, without causing an error.
29+
- An example `file.dqlpart` file: `filter field > 10 | sort field desc`
30+
- Support for `.partial.dql` files will be removed in the future, so it's recommended to migrate to the new extension
31+
as soon as possible.
2432
- **Breaking**: Changing the approach to the default Dynatrace tenant used for connections - it will be the first tenant
2533
specified in the list (previously the user needed to specifically select the default one).
2634
- Created Wiki pages with documentation for the plugin features
2735
- DQL now supports complex sorting expressions (for example, `sort abs(field) > 10 desc`)
2836
- Added missing quick fixes for inspections:
2937
- Dropping DQL commands and functions for unknown & experimental expressions
30-
- Renaming the DQL file to `.partial.dql` when an invalid command context is detected (only for `.dql` files)
38+
- Renaming the DQL file to `.dqlpart` when an invalid command context is detected (only for `.dql` files)
3139
- DQL now supports `/* language=X */` comments in strings
3240
- Adding a Dynatrace Query Console view that allows the user to execute DQL queries without opening a DQL file.
3341
You can open the console via the `Tools` -> `Services` -> `Dynatrace Query Console` menu or by clicking the `+` button
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ tenant is configured.
1111

1212
## Features
1313

14-
The `.dqlexpr` files inherit features from the [Dynatrace Query Language (`.dql`)](./DQL) files. Inspections related to
15-
the expression context (like assignment support) are disabled for such files.
14+
The `.dqlexpr` files inherit features from the [Dynatrace Query Language (`.dql`)](./DQL) files.
15+
Inspections related to the expression context (like validating assignment support) are disabled for such files.
1616

17-
## Example `.dqlexpr` file
17+
## Usage
1818

19-
```dqlexpr
19+
### Example `.dqlexpr` file
20+
21+
```DQLExpr
2022
matchesPhrase(event.provider, \"my-provider-*\") OR matchesPhrase(event.provider, \"*.my.host\")
2123
```

docs/wiki/DQL-Part.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Dynatrace Query Language parts
2+
3+
The `DQLPart` language is a DQL query that disables validation for the query context. This allows you to write DQL
4+
queries in smaller parts without raising errors related to a wrong DQL command usage.
5+
6+
This is especially useful for dynamic DQL generators, where you define a base part of the query and then add more
7+
commands to it based on some conditions.
8+
9+
## Features
10+
11+
The `.dqlpart` files inherit features from the [Dynatrace Query Language (`.dql`)](./DQL) files.
12+
You will not be able to execute such files and automatic tenant verification will be disabled for them, as they will
13+
most likely never be a valid DQL query on their own.
14+
15+
## Usage
16+
17+
### Example `.dqlpart` file
18+
19+
```DQLPart
20+
| filter event.provider = "my-provider"
21+
```
22+
23+
### Example dynamic generator
24+
25+
```Java
26+
public class Example {
27+
public static final String BASE_QUERY = /* language=DQL */ """
28+
fetch events, bucket: {"my-bucket"}, from: -1h
29+
""";
30+
31+
public String generateQuery(boolean withFilter) {
32+
String query = BASE_QUERY;
33+
if (withFilter) {
34+
query += /* language=DQLPart */ """
35+
| filter event.provider == "my-provider"
36+
""";
37+
}
38+
return query;
39+
}
40+
}
41+
```

docs/wiki/DQL.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ the most common parts of statements and include them into other DQL files.
247247
This most probably will mean that one of those files will not be a valid DQL by itself, as it will not start with
248248
a data source command like `fetch`.
249249

250-
Renaming your file to `NAME.partial.dql` will silence the errors about the invalid command context and will disable the
251-
requirement of prepending every command with a pipe (`|`) sign. Additionally, the partial file will not execute the
252-
background DQL verification on your tenant, as it would always fail.
250+
You can store smaller parts of DQL queries in dedicated sublanguages:
251+
252+
- [Expressions DQL](./DQL-Expression.md) - specify only expressions without the DQL command context
253+
- [DQL Part](./DQL-Part.md) - specify DQL command usages without the need to follow the full DQL syntax rules

docs/wiki/Home.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ subpages:
3030

3131
- [Dynatrace Query Language (DQL)](./DQL)
3232
- [Dynatrace Pattern Language (DPL)](./DPL)
33-
- [Expressions DQL](./DQL_Expression.md) - smaller subset of DQL files, allowing to specify only expressions
33+
- [Expressions DQL](./DQL-Expression.md) - smaller subset of DQL files, allowing to specify only expressions
3434
without the DQL command context
35+
- [DQL Part](./DQL-Part.md) - smaller parts of the DQL queries, useful for dynamic DQL generators
3536

3637
## Frequently Asked Questions (FAQ)
3738

src/main/java/pl/thedeem/intellij/dql/DQLUtil.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import pl.thedeem.intellij.dql.psi.DQLParenthesisedExpression;
2121
import pl.thedeem.intellij.dql.psi.DQLVariableExpression;
2222
import pl.thedeem.intellij.dql.settings.DQLSettings;
23+
import pl.thedeem.intellij.dqlpart.DQLPartFileType;
2324

2425
import java.time.Instant;
2526
import java.time.ZoneId;
@@ -59,9 +60,8 @@ public class DQLUtil {
5960
private final static String PARTIAL_DQL_NAME = ".partial.";
6061
private final static String CREDENTIALS_PREFIX = "pl.thedeem.intellij.dql/";
6162

62-
public static boolean isPartialFile(final PsiFile file) {
63-
String name = file.getName();
64-
return name.contains(PARTIAL_DQL_NAME);
63+
public static boolean isPartialFile(@NotNull PsiFile file) {
64+
return DQLPartFileType.INSTANCE.equals(file.getFileType()) || file.getName().contains(PARTIAL_DQL_NAME);
6565
}
6666

6767
public static List<DQLFieldExpression> findFieldsInFile(PsiFile file, String key) {

src/main/java/pl/thedeem/intellij/dql/actions/ExecuteDQLQueryAction.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import pl.thedeem.intellij.common.services.ProjectServicesManager;
1010
import pl.thedeem.intellij.dql.DQLBundle;
1111
import pl.thedeem.intellij.dql.DQLFileType;
12+
import pl.thedeem.intellij.dql.DQLUtil;
1213
import pl.thedeem.intellij.dql.DynatraceQueryLanguage;
1314
import pl.thedeem.intellij.dql.definition.model.QueryConfiguration;
1415
import pl.thedeem.intellij.dql.exec.DQLExecutionService;
@@ -93,6 +94,9 @@ protected boolean isNotRelatedToDQL(@NotNull AnActionEvent e) {
9394
if (PsiTreeUtil.getChildrenOfType(file, DQLQuery.class) == null) {
9495
return true;
9596
}
97+
if (DQLUtil.isPartialFile(file)) {
98+
return true;
99+
}
96100
Language[] langs = e.getData(LangDataKeys.CONTEXT_LANGUAGES);
97101
return langs == null || !List.of(langs).contains(DynatraceQueryLanguage.INSTANCE);
98102
}

src/main/java/pl/thedeem/intellij/dql/inspections/commands/InvalidCommandContextInspection.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.intellij.codeInspection.LocalQuickFix;
55
import com.intellij.codeInspection.ProblemsHolder;
66
import com.intellij.lang.injection.InjectedLanguageManager;
7+
import com.intellij.openapi.util.text.StringUtil;
78
import com.intellij.psi.PsiElement;
89
import com.intellij.psi.PsiElementVisitor;
910
import org.jetbrains.annotations.NotNull;
@@ -76,15 +77,12 @@ public void visitCommand(@NotNull DQLCommand command) {
7677
}
7778

7879
private static @NotNull String proposePartialName(@NotNull String name) {
79-
if (name.contains(".partial.")) {
80+
if (StringUtil.endsWithIgnoreCase(name, ".dqlpart")) {
8081
return name;
8182
}
82-
int dot = name.lastIndexOf('.');
83-
if (dot <= 0) {
84-
return name + ".partial.dql";
83+
if (StringUtil.endsWithIgnoreCase(name, ".dql")) {
84+
return name + "part";
8585
}
86-
String base = name.substring(0, dot);
87-
String ext = name.substring(dot);
88-
return base + ".partial." + ext.substring(1);
86+
return name + ".dqlpart";
8987
}
9088
}

src/main/java/pl/thedeem/intellij/dql/inspections/fixes/RenameFileQuickFix.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package pl.thedeem.intellij.dql.inspections.fixes;
22

3+
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
34
import com.intellij.codeInspection.LocalQuickFix;
45
import com.intellij.codeInspection.ProblemDescriptor;
56
import com.intellij.openapi.project.Project;
@@ -16,6 +17,11 @@ public class RenameFileQuickFix implements LocalQuickFix {
1617
public RenameFileQuickFix(@NotNull String proposedName) {
1718
this.proposedName = proposedName;
1819
}
20+
21+
@Override
22+
public @NotNull IntentionPreviewInfo generatePreview(@NotNull Project project, @NotNull ProblemDescriptor previewDescriptor) {
23+
return IntentionPreviewInfo.EMPTY;
24+
}
1925

2026
@Override
2127
public @NotNull String getFamilyName() {

src/main/java/pl/thedeem/intellij/dql/inspections/fixes/ReplaceFetchWithMetricsQuickFix.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
import org.jetbrains.annotations.Nullable;
88
import pl.thedeem.intellij.common.quickFixes.AbstractReplaceElementQuickFix;
99
import pl.thedeem.intellij.dql.DQLBundle;
10-
import pl.thedeem.intellij.dql.services.definition.DQLDefinitionService;
1110
import pl.thedeem.intellij.dql.definition.model.Command;
1211
import pl.thedeem.intellij.dql.definition.model.MappedParameter;
1312
import pl.thedeem.intellij.dql.definition.model.Parameter;
1413
import pl.thedeem.intellij.dql.psi.DQLCommand;
14+
import pl.thedeem.intellij.dql.services.definition.DQLDefinitionService;
1515

1616
import java.util.List;
1717
import java.util.Set;
@@ -43,7 +43,7 @@ public class ReplaceFetchWithMetricsQuickFix extends AbstractReplaceElementQuick
4343
@NotNull
4444
@Override
4545
public String getName() {
46-
return DQLBundle.message("inspection.variable.metricSeriesMigration.issueDetected.fix");
46+
return DQLBundle.message("inspection.metricSeriesMigration.issueDetected.fix");
4747
}
4848

4949
@Override

0 commit comments

Comments
 (0)