这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func rootCommand() *cobra.Command {
pluginCmd(),
compactCmd(),
sourceCmd(),
tableCmd(),
)

// disable auto completion generation, since we don't want to support
Expand Down
146 changes: 146 additions & 0 deletions cmd/table.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package cmd

import (
"context"
"fmt"
"strings"

"github.com/spf13/cobra"
"github.com/thediveo/enumflag/v2"

"github.com/turbot/go-kit/helpers"
"github.com/turbot/pipe-fittings/cmdconfig"
pconstants "github.com/turbot/pipe-fittings/constants"
"github.com/turbot/pipe-fittings/contexthelpers"
"github.com/turbot/pipe-fittings/error_helpers"
"github.com/turbot/pipe-fittings/printers"
"github.com/turbot/pipe-fittings/utils"
"github.com/turbot/tailpipe/internal/constants"
"github.com/turbot/tailpipe/internal/display"
)

func tableCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "table [command]",
Args: cobra.NoArgs,
Short: "Tailpipe table commands.",
Long: `Tailpipe table commands.

Tables define the structure of the data that is collected by Tailpipe.

Examples:

# List all tables
tailpipe table list

# Show details for a specific table
tailpipe table show aws_cloudtrail_log`,
}

cmd.AddCommand(tableListCmd())
cmd.AddCommand(tableShowCmd())

cmd.Flags().BoolP(pconstants.ArgHelp, "h", false, "Help for table")

return cmd
}

// List Tables
func tableListCmd() *cobra.Command {
var cmd = &cobra.Command{
Use: "list",
Args: cobra.NoArgs,
Run: runTableListCmd,
Short: "List all tables.",
Long: `List all tables.`,
}

cmdconfig.
OnCmd(cmd).
AddVarFlag(enumflag.New(&pluginOutputMode, pconstants.ArgOutput, constants.PluginOutputModeIds, enumflag.EnumCaseInsensitive),
pconstants.ArgOutput,
fmt.Sprintf("Output format; one of: %s", strings.Join(constants.FlagValues(constants.PluginOutputModeIds), ", "))).
AddBoolFlag(pconstants.ArgHelp, false, "Help for table list", cmdconfig.FlagOptions.WithShortHand("h"))

return cmd
}

func runTableListCmd(cmd *cobra.Command, args []string) {
//setup a cancel context and start cancel handler
ctx, cancel := context.WithCancel(cmd.Context())
contexthelpers.StartCancelHandler(cancel)
utils.LogTime("runSourceListCmd start")
defer func() {
utils.LogTime("runSourceListCmd end")
if r := recover(); r != nil {
error_helpers.ShowError(ctx, helpers.ToError(r))
exitCode = pconstants.ExitCodeUnknownErrorPanic
}
}()

// Get Resources
resources, err := display.ListTableResources(ctx)
error_helpers.FailOnError(err)
printableResource := display.NewPrintableResource(resources...)

// Get Printer
printer, err := printers.GetPrinter[*display.TableResource](cmd)
error_helpers.FailOnError(err)

// Print
err = printer.PrintResource(ctx, printableResource, cmd.OutOrStdout())
if err != nil {
error_helpers.ShowError(ctx, err)
exitCode = pconstants.ExitCodeUnknownErrorPanic
}
}

// Show Table
func tableShowCmd() *cobra.Command {
var cmd = &cobra.Command{
Use: "show <table>",
Args: cobra.ExactArgs(1),
Run: runTableShowCmd,
Short: "Show details for a specific table.",
Long: `Show details for a specific table.`,
}

cmdconfig.
OnCmd(cmd).
AddVarFlag(enumflag.New(&pluginOutputMode, pconstants.ArgOutput, constants.PluginOutputModeIds, enumflag.EnumCaseInsensitive),
pconstants.ArgOutput,
fmt.Sprintf("Output format; one of: %s", strings.Join(constants.FlagValues(constants.PluginOutputModeIds), ", "))).
AddBoolFlag(pconstants.ArgHelp, false, "Help for table show", cmdconfig.FlagOptions.WithShortHand("h"))

return cmd
}

func runTableShowCmd(cmd *cobra.Command, args []string) {
//setup a cancel context and start cancel handler
ctx, cancel := context.WithCancel(cmd.Context())
contexthelpers.StartCancelHandler(cancel)
utils.LogTime("runTableShowCmd start")
defer func() {
utils.LogTime("runTableShowCmd end")
if r := recover(); r != nil {
error_helpers.ShowError(ctx, helpers.ToError(r))
exitCode = pconstants.ExitCodeUnknownErrorPanic
}
}()

// Get Resources
resource, err := display.GetTableResource(ctx, args[0])
error_helpers.FailOnError(err)
printableResource := display.NewPrintableResource(resource)

// Get Printer
printer, err := printers.GetPrinter[*display.TableResource](cmd)
error_helpers.FailOnError(err)

// Print
err = printer.PrintResource(ctx, printableResource, cmd.OutOrStdout())
if err != nil {
error_helpers.ShowError(ctx, err)
exitCode = pconstants.ExitCodeUnknownErrorPanic
}
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ require (
github.com/charmbracelet/bubbletea v1.1.0
github.com/charmbracelet/lipgloss v0.13.0
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964
github.com/dustin/go-humanize v1.0.1
github.com/fsnotify/fsnotify v1.7.0
github.com/gdamore/tcell/v2 v2.7.4
github.com/gertd/go-pluralize v0.2.1
Expand All @@ -37,6 +38,7 @@ require (
github.com/rivo/tview v0.0.0-20240818110301-fd649dbf1223
github.com/sethvargo/go-retry v0.2.4
github.com/thediveo/enumflag/v2 v2.0.5
golang.org/x/sync v0.8.0
golang.org/x/term v0.25.0
)

Expand Down Expand Up @@ -201,7 +203,6 @@ require (
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/oauth2 v0.22.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.5.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
Expand Down
31 changes: 31 additions & 0 deletions internal/database/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"database/sql"
"fmt"
"os"
"regexp"
"strings"

"github.com/turbot/tailpipe/internal/config"
"github.com/turbot/tailpipe/internal/filepaths"
)

// AddTableViews creates a view for each table in the data directory, applying the provided duck db filters to the view query
Expand Down Expand Up @@ -131,3 +133,32 @@ func getDirNames(folderPath string) ([]string, error) {

return dirNames, nil
}

func GetRowCount(ctx context.Context, tableName string) (int64, error) {
// Open a DuckDB connection
db, err := sql.Open("duckdb", filepaths.TailpipeDbFilePath())
if err != nil {
return 0, fmt.Errorf("failed to open DuckDB connection: %w", err)
}
defer db.Close()

var tableNameRegex = regexp.MustCompile(`^[a-zA-Z0-9_]+$`)
if !tableNameRegex.MatchString(tableName) {
return 0, fmt.Errorf("invalid table name")
}
query := fmt.Sprintf("SELECT COUNT(*) FROM %s", tableName) // #nosec G201 // this is a controlled query tableName must match a regex
rows, err := db.QueryContext(ctx, query)
if err != nil {
return 0, fmt.Errorf("failed to get row count: %w", err)
}
defer rows.Close()

var count int64
if rows.Next() {
err = rows.Scan(&count)
if err != nil {
return 0, fmt.Errorf("failed to scan row count: %w", err)
}
}
return count, nil
}
Loading
Loading