From b92ff8a07477bfd52ffeae9042a04544f2ca50ff Mon Sep 17 00:00:00 2001 From: Binaek Sarkar Date: Tue, 7 Dec 2021 18:27:19 +0530 Subject: [PATCH] Enables the `tablefunc` extension for the `steampipe` database. Closes #1154 --- db/db_local/install.go | 12 ++++---- db/db_local/start_services.go | 29 ++++++++++++++++++ .../templates/expected_crosstab_results.txt | 5 ++++ .../test_files/018.dynamic-schema.bats | 4 +-- .../test_files/020.service_extensions.bats | 30 +++++++++++++++++++ 5 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 tests/acceptance/test_data/templates/expected_crosstab_results.txt create mode 100644 tests/acceptance/test_files/020.service_extensions.bats diff --git a/db/db_local/install.go b/db/db_local/install.go index 38b67d5e7..286af3495 100644 --- a/db/db_local/install.go +++ b/db/db_local/install.go @@ -244,6 +244,11 @@ func runInstall(firstInstall bool, spinner *spinner.Spinner) error { display.StopSpinner(spinner) return fmt.Errorf("Connection to database... FAILED!") } + defer func() { + display.UpdateSpinnerMessage(spinner, "Completing configuration") + client.Close() + doThreeStepPostgresExit(process) + }() display.UpdateSpinnerMessage(spinner, "Generating database passwords...") // generate a password file for use later @@ -285,13 +290,6 @@ func runInstall(firstInstall bool, spinner *spinner.Spinner) error { return fmt.Errorf("Configuring Steampipe... FAILED!") } - // close the client - otherwise, it may be difficult to stop the service - client.Close() - - // force stop - display.UpdateSpinnerMessage(spinner, "Completing configuration") - err = doThreeStepPostgresExit(process) - return err } diff --git a/db/db_local/start_services.go b/db/db_local/start_services.go index c8b6ed6ae..c2058ca86 100644 --- a/db/db_local/start_services.go +++ b/db/db_local/start_services.go @@ -11,6 +11,7 @@ import ( "sync" "syscall" + "github.com/turbot/steampipe/db/db_common" "github.com/turbot/steampipe/plugin_manager" psutils "github.com/shirou/gopsutil/process" @@ -180,6 +181,13 @@ func startDB(port int, listen StartListenType, invoker constants.Invoker) (start return ServiceFailedToStart, err } + // ensure that the necessary extensions are installed in the database + err = ensurePgExtensions(databaseName) + if err != nil { + // there was a problem with the installation + return ServiceFailedToStart, err + } + err = ensureTempTablePermissions(databaseName) if err != nil { return ServiceFailedToStart, err @@ -438,6 +446,27 @@ func setupLogCollector(postgresCmd *exec.Cmd) (chan string, func(), error) { return publishChannel, closeFunction, nil } +// ensures that the necessary extensions are installed on the database +func ensurePgExtensions(databaseName string) error { + extensions := []string{ + "tablefunc", + } + + errors := []error{} + rootClient, err := createLocalDbClient(&CreateDbOptions{DatabaseName: databaseName, Username: constants.DatabaseSuperUser}) + if err != nil { + return err + } + defer rootClient.Close() + for _, extn := range extensions { + _, err = rootClient.Exec(fmt.Sprintf("create extension if not exists %s", db_common.PgEscapeName(extn))) + if err != nil { + errors = append(errors, err) + } + } + return utils.CombineErrors(errors...) +} + // ensures that the 'steampipe' foreign server exists // (re)install FDW and creates server if it doesn't func ensureSteampipeServer(databaseName string) error { diff --git a/tests/acceptance/test_data/templates/expected_crosstab_results.txt b/tests/acceptance/test_data/templates/expected_crosstab_results.txt new file mode 100644 index 000000000..838f7825e --- /dev/null +++ b/tests/acceptance/test_data/templates/expected_crosstab_results.txt @@ -0,0 +1,5 @@ ++----------+------------+------------+ +| row_name | category_1 | category_2 | ++----------+------------+------------+ +| test1 | val2 | val3 | ++----------+------------+------------+ \ No newline at end of file diff --git a/tests/acceptance/test_files/018.dynamic-schema.bats b/tests/acceptance/test_files/018.dynamic-schema.bats index 0a2b883a3..0e579893c 100644 --- a/tests/acceptance/test_files/018.dynamic-schema.bats +++ b/tests/acceptance/test_files/018.dynamic-schema.bats @@ -55,7 +55,7 @@ load "$LIB_BATS_SUPPORT/load.bash" rm -f $FILE_PATH/test_data/csv_plugin_test/b.csv # run the query and verify - should fail -run steampipe query "select * from csv1.b" + run steampipe query "select * from csv1.b" assert_output --partial 'does not exist' rm -f $FILE_PATH/test_data/csv_plugin_test/b.csv @@ -90,6 +90,6 @@ function setup() { function teardown() { # remove the files created as part of these tests - rm -f $STEAMPIPE_INSTALL_DIR/config/csv1.spc + rm -f $STEAMPIPE_INSTALL_DIR/config/csv*.spc rm -f output.* } \ No newline at end of file diff --git a/tests/acceptance/test_files/020.service_extensions.bats b/tests/acceptance/test_files/020.service_extensions.bats new file mode 100644 index 000000000..8cfc3f7b7 --- /dev/null +++ b/tests/acceptance/test_files/020.service_extensions.bats @@ -0,0 +1,30 @@ +load "$LIB_BATS_ASSERT/load.bash" +load "$LIB_BATS_SUPPORT/load.bash" + +# tests for tablefunc module + +@test "test crosstab function" { + # create table and insert values + steampipe query "CREATE TABLE ct(id SERIAL, rowid TEXT, attribute TEXT, value TEXT);" + steampipe query "INSERT INTO ct(rowid, attribute, value) VALUES('test1','att1','val1');" + steampipe query "INSERT INTO ct(rowid, attribute, value) VALUES('test1','att2','val2');" + steampipe query "INSERT INTO ct(rowid, attribute, value) VALUES('test1','att3','val3');" + + # crosstab function + run steampipe query "SELECT * FROM crosstab('select rowid, attribute, value from ct where attribute = ''att2'' or attribute = ''att3'' order by 1,2') AS ct(row_name text, category_1 text, category_2 text);" + echo $output + + # drop table + steampipe query "DROP TABLE ct" + + # match output with expected + assert_equal "$output" "$(cat $TEST_DATA_DIR/expected_crosstab_results.txt)" +} + +@test "test normal_rand function" { + # normal_rand function + steampipe query "SELECT * FROM normal_rand(10, 5, 3);" + + # previous query should pass + assert_success +}