feat: Implement reliable direct child directory searches
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user