Skip to content

Commit

Permalink
fix table/column metadata queries for autocomplete
Browse files Browse the repository at this point in the history
  • Loading branch information
hrl20 committed Sep 24, 2024
1 parent abd66dd commit 97b079e
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 102 deletions.
72 changes: 0 additions & 72 deletions Magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,80 +4,8 @@
package main

import (
"encoding/json"
"fmt"
"os"
"os/exec"
"path"
"strings"

// mage:import
build "github.com/grafana/grafana-plugin-sdk-go/build"
"github.com/magefile/mage/mg"
)

var defaultOutputBinaryPath = "dist"
var defaultPluginJSONPath = "src"

// Build is a namespace.
type Build mg.Namespace

func GetStringValueFromJSON(fpath string, key string) (string, error) {
byteValue, err := os.ReadFile(fpath)
if err != nil {
return "", err
}

var result map[string]interface{}
err = json.Unmarshal(byteValue, &result)
if err != nil {
return "", err
}
executable := result[key]
name, ok := executable.(string)
if !ok || name == "" {
return "", fmt.Errorf("plugin.json is missing: %s", key)
}
return name, nil
}

func GetExecutableFromPluginJSON(dir string) (string, error) {
exe, err := GetStringValueFromJSON(path.Join(dir, "plugin.json"), "executable")
if err != nil {
// In app plugins, the exe may be nested
exe, err2 := GetStringValueFromJSON(path.Join(dir, "datasource", "plugin.json"), "executable")
if err2 == nil {
if !strings.HasPrefix(exe, "../") {
return "", fmt.Errorf("datasource should reference executable in root folder")
}
return exe[3:], nil
}
}
return exe, err
}

func getEnvironment(check ...string) string {
for _, key := range check {
if strings.HasPrefix(key, "> ") {
parts := strings.Split(key, " ")
cmd := exec.Command(parts[1], parts[2:]...) // #nosec G204
out, err := cmd.CombinedOutput()
if err == nil && len(out) > 0 {
str := strings.TrimSpace(string(out))
if strings.Index(str, " ") > 0 {
continue // skip any output that has spaces
}
return str
}
continue
}

val := os.Getenv(key)
if val != "" {
return strings.TrimSpace(val)
}
}
return ""
}

var Default = build.BuildAll
1 change: 0 additions & 1 deletion pkg/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ func main() {
// from Grafana to create different instances of SampleDatasource (per datasource
// ID). When datasource configuration changed Dispose method will be called and
// new datasource instance created using NewSampleDatasource factory.
// duckdbconnector, err := duckdb.NewConnector(":memory:", nil)

if err := datasource.Manage("motherduck-duckdb-datasource", datasourceFactory, datasource.ManageOpts{}); err != nil {
log.DefaultLogger.Error(err.Error())
Expand Down
32 changes: 3 additions & 29 deletions src/datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,8 @@ interface CompletionProviderGetterArgs {
}


function buildSchemaConstraint() {
// quote_ident protects hyphenated schemes
return `
quote_ident(table_schema) IN (
SELECT
CASE WHEN trim(s[i]) = '"$user"' THEN user ELSE trim(s[i]) END
FROM
generate_series(
array_lower(string_to_array(current_setting('search_path'),','),1),
array_upper(string_to_array(current_setting('search_path'),','),1)
) as i,
string_to_array(current_setting('search_path'),',') s
)`;
}

function showTables() {
return `select quote_ident(table_name) as "table" from information_schema.tables
where quote_ident(table_schema) not in ('information_schema',
'pg_catalog',
'_timescaledb_cache',
'_timescaledb_catalog',
'_timescaledb_internal',
'_timescaledb_config',
'timescaledb_information',
'timescaledb_experimental')
and ${buildSchemaConstraint()}`;
return `select table_name as "table" from information_schema.tables`;
}


Expand All @@ -54,14 +30,12 @@ function getSchema(table: string) {
// in the table-name
const tableNamePart = "'" + table.replace(/'/g, "''") + "'";

return `select quote_ident(column_name) as "column", data_type as "type"
return `select column_name as "column", data_type as "type"
from information_schema.columns
where quote_ident(table_name) = ${tableNamePart};
`;
where table_name = ${tableNamePart};`;
}



const getSqlCompletionProvider: (args: CompletionProviderGetterArgs) => LanguageCompletionProvider =
({ getColumns, getTables }) =>
(monaco, language) => ({
Expand Down

0 comments on commit 97b079e

Please sign in to comment.