feat: Implement reliable direct child directory searches

This commit is contained in:
Felicitas Pojtinger
2021-11-28 22:56:27 +01:00
parent 35a447a9cc
commit 5f3d3598d8
7 changed files with 69 additions and 39 deletions

View File

@@ -9,7 +9,7 @@ import (
"github.com/volatiletech/sqlboiler/v4/boil"
)
var ejectCmd = &cobra.Command{
var driveEjectCmd = &cobra.Command{
Use: "eject",
Aliases: []string{"e"},
Short: "Eject the tape (tape only)",
@@ -35,5 +35,5 @@ var ejectCmd = &cobra.Command{
func init() {
viper.AutomaticEnv()
driveCmd.AddCommand(ejectCmd)
driveCmd.AddCommand(driveEjectCmd)
}

View File

@@ -10,7 +10,7 @@ import (
"github.com/volatiletech/sqlboiler/v4/boil"
)
var tellCmd = &cobra.Command{
var driveTellCmd = &cobra.Command{
Use: "tell",
Aliases: []string{"t"},
Short: "Get the current record (tape only)",
@@ -43,5 +43,5 @@ var tellCmd = &cobra.Command{
func init() {
viper.AutomaticEnv()
driveCmd.AddCommand(tellCmd)
driveCmd.AddCommand(driveTellCmd)
}

View File

@@ -11,10 +11,10 @@ import (
"github.com/volatiletech/sqlboiler/v4/boil"
)
var queryCmd = &cobra.Command{
Use: "query",
Aliases: []string{"q"},
Short: "Query the contents of an index",
var listCmd = &cobra.Command{
Use: "list",
Aliases: []string{"l"},
Short: "List the contents of a directory in the index",
RunE: func(cmd *cobra.Command, args []string) error {
if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil {
return err
@@ -56,9 +56,9 @@ var queryCmd = &cobra.Command{
}
func init() {
queryCmd.PersistentFlags().StringP(nameFlag, "n", "", "Name of the file or directory to query")
listCmd.PersistentFlags().StringP(nameFlag, "n", "", "Directory to list the contents of")
viper.AutomaticEnv()
rootCmd.AddCommand(queryCmd)
rootCmd.AddCommand(listCmd)
}

View File

@@ -20,7 +20,7 @@ import (
"github.com/volatiletech/sqlboiler/v4/boil"
)
var indexCmd = &cobra.Command{
var recoveryIndexCmd = &cobra.Command{
Use: "index",
Aliases: []string{"i"},
Short: "Index contents of tape or tar file",
@@ -216,14 +216,14 @@ func index(
}
func init() {
indexCmd.PersistentFlags().IntP(recordSizeFlag, "e", 20, "Amount of 512-bit blocks per record")
indexCmd.PersistentFlags().IntP(recordFlag, "r", 0, "Record to seek too before counting")
indexCmd.PersistentFlags().IntP(blockFlag, "b", 0, "Block in record to seek too before counting")
indexCmd.PersistentFlags().BoolP(overwriteFlag, "o", false, "Remove the old index before starting to index")
recoveryIndexCmd.PersistentFlags().IntP(recordSizeFlag, "e", 20, "Amount of 512-bit blocks per record")
recoveryIndexCmd.PersistentFlags().IntP(recordFlag, "r", 0, "Record to seek too before counting")
recoveryIndexCmd.PersistentFlags().IntP(blockFlag, "b", 0, "Block in record to seek too before counting")
recoveryIndexCmd.PersistentFlags().BoolP(overwriteFlag, "o", false, "Remove the old index before starting to index")
viper.AutomaticEnv()
recoveryCmd.AddCommand(indexCmd)
recoveryCmd.AddCommand(recoveryIndexCmd)
}
func indexHeader(record, block int64, hdr *tar.Header, metadataPersister *persisters.MetadataPersister) error {

View File

@@ -14,7 +14,7 @@ import (
"github.com/volatiletech/sqlboiler/v4/boil"
)
var listCmd = &cobra.Command{
var recoveryListCmd = &cobra.Command{
Use: "list",
Aliases: []string{"l"},
Short: "List contents of tape or tar file",
@@ -184,11 +184,11 @@ var listCmd = &cobra.Command{
}
func init() {
listCmd.PersistentFlags().IntP(recordSizeFlag, "e", 20, "Amount of 512-bit blocks per record")
listCmd.PersistentFlags().IntP(recordFlag, "r", 0, "Record to seek too before counting")
listCmd.PersistentFlags().IntP(blockFlag, "b", 0, "Block in record to seek too before counting")
recoveryListCmd.PersistentFlags().IntP(recordSizeFlag, "e", 20, "Amount of 512-bit blocks per record")
recoveryListCmd.PersistentFlags().IntP(recordFlag, "r", 0, "Record to seek too before counting")
recoveryListCmd.PersistentFlags().IntP(blockFlag, "b", 0, "Block in record to seek too before counting")
viper.AutomaticEnv()
recoveryCmd.AddCommand(listCmd)
recoveryCmd.AddCommand(recoveryListCmd)
}

View File

@@ -21,7 +21,7 @@ const (
previewFlag = "preview"
)
var restoreCmd = &cobra.Command{
var recoveryRestoreCmd = &cobra.Command{
Use: "restore",
Aliases: []string{"r"},
Short: "Restore a file",
@@ -105,13 +105,13 @@ var restoreCmd = &cobra.Command{
}
func init() {
restoreCmd.PersistentFlags().IntP(recordSizeFlag, "e", 20, "Amount of 512-bit blocks per record")
restoreCmd.PersistentFlags().IntP(recordFlag, "r", 0, "Record to seek too")
restoreCmd.PersistentFlags().IntP(blockFlag, "b", 0, "Block in record to seek too")
restoreCmd.PersistentFlags().StringP(dstFlag, "d", "", "File to restore to (archived name by default)")
restoreCmd.PersistentFlags().BoolP(previewFlag, "p", false, "Only read the header")
recoveryRestoreCmd.PersistentFlags().IntP(recordSizeFlag, "e", 20, "Amount of 512-bit blocks per record")
recoveryRestoreCmd.PersistentFlags().IntP(recordFlag, "r", 0, "Record to seek too")
recoveryRestoreCmd.PersistentFlags().IntP(blockFlag, "b", 0, "Block in record to seek too")
recoveryRestoreCmd.PersistentFlags().StringP(dstFlag, "d", "", "File to restore to (archived name by default)")
recoveryRestoreCmd.PersistentFlags().BoolP(previewFlag, "p", false, "Only read the header")
viper.AutomaticEnv()
recoveryCmd.AddCommand(restoreCmd)
recoveryCmd.AddCommand(recoveryRestoreCmd)
}

View File

@@ -114,27 +114,57 @@ func (p *MetadataPersister) GetHeaderChildren(ctx context.Context, name string)
}
func (p *MetadataPersister) GetHeaderDirectChildren(ctx context.Context, name string) (models.HeaderSlice, error) {
if name == "" || name == "." || name == "/" {
return p.GetHeaders(ctx)
prefix := strings.TrimSuffix(name, "/") + "/"
// Root node
if name == "" || name == "." || name == "/" || name == "./" {
prefix = ""
}
prefixWithoutTrailingSlash := strings.TrimSuffix(name, "/")
prefixWithTrailingSlash := prefixWithoutTrailingSlash + "/%"
headers := models.HeaderSlice{}
if err := queries.Raw(
fmt.Sprintf(
`select * from %v where %v = ? or %v = ? or (%v like ? and %v not like ?)`,
`select %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v,
length(replace(%v, ?, '')) - length(replace(replace(%v, ?, ''), '/', '')) as depth
from %v
where %v like ?
and (
depth = 0
or (
%v like '%%/'
and depth = 1
)
)
and not %v in ('', '.', '/', './');`,
models.HeaderColumns.Record,
models.HeaderColumns.Block,
models.HeaderColumns.Typeflag,
models.HeaderColumns.Name,
models.HeaderColumns.Linkname,
models.HeaderColumns.Size,
models.HeaderColumns.Mode,
models.HeaderColumns.UID,
models.HeaderColumns.Gid,
models.HeaderColumns.Uname,
models.HeaderColumns.Gname,
models.HeaderColumns.Modtime,
models.HeaderColumns.Accesstime,
models.HeaderColumns.Changetime,
models.HeaderColumns.Devmajor,
models.HeaderColumns.Devminor,
models.HeaderColumns.Paxrecords,
models.HeaderColumns.Format,
models.HeaderColumns.Name,
models.HeaderColumns.Name,
models.TableNames.Headers,
models.HeaderColumns.Name,
models.HeaderColumns.Name,
models.HeaderColumns.Name,
models.HeaderColumns.Name,
),
prefixWithoutTrailingSlash,
prefixWithTrailingSlash,
prefixWithTrailingSlash,
prefixWithTrailingSlash+"/%",
prefix,
prefix,
prefix+"%",
).Bind(ctx, p.db, &headers); err != nil {
if err == sql.ErrNoRows {
return headers, nil