go-perm-test/main_windows.go

144 lines
3.6 KiB
Go
Raw Normal View History

2024-08-19 22:30:30 +00:00
package main
import (
2024-08-20 03:23:58 +00:00
"errors"
2024-08-19 22:30:30 +00:00
"fmt"
"io/fs"
"os"
"strings"
"zombiezen.com/go/sqlite"
"zombiezen.com/go/sqlite/sqlitex"
)
type Result struct{ Expected, Actual fs.FileMode }
type SQLiteEmitter struct {
conn *sqlite.Conn
}
func (s *SQLiteEmitter) Close() error {
return s.conn.Close()
}
func sqlViewColSpec() string {
var cols []string
var whos = []rune{'o', 'g', 'u'}
var whats = []rune{'x', 'w', 'r'}
for _, fieldName := range []string{"expected", "actual"} {
cols = append(cols, fmt.Sprintf("%s", fieldName))
for iwho, who := range whos {
cols = append(cols, fmt.Sprintf("%[1]s & (7 << %[3]d * 3) >> (%[3]d * 3) AS %[1]s_%[2]c", fieldName, who, iwho))
for iwhat, what := range whats {
cols = append(cols, fmt.Sprintf("%[1]s & (1 << %[3]d * 3 + %[5]d) >> (%[3]d * 3 + %[5]d) AS %[1]s_%[2]c%[4]c", fieldName, who, iwho, what, iwhat))
}
}
}
return strings.Join(cols, ",\n")
}
2024-08-20 03:23:58 +00:00
const createTableFile = `CREATE TABLE file_result_raw (
2024-08-19 22:30:30 +00:00
expected INT NOT NULL,
actual INT NOT NULL
);`
2024-08-20 03:23:58 +00:00
var createViewFile string = `CREATE VIEW file_result AS
2024-08-19 22:30:30 +00:00
SELECT
` + sqlViewColSpec() + `
2024-08-20 03:23:58 +00:00
FROM file_result_raw;`
var createTableDir = strings.ReplaceAll(createTableFile, "file_result", "dir_result")
var createViewDir = strings.ReplaceAll(createViewFile, "file_result", "dir_result")
2024-08-19 22:30:30 +00:00
func NewSQLite(path string) (*SQLiteEmitter, error) {
conn, err := sqlite.OpenConn(path, sqlite.OpenCreate|sqlite.OpenReadWrite|sqlite.OpenWAL)
if err != nil {
return nil, err
}
2024-08-20 03:23:58 +00:00
script := strings.Join([]string{createTableFile, createTableDir, createViewFile, createViewDir}, "\n")
fmt.Println(script)
err = sqlitex.ExecuteScript(conn, script, &sqlitex.ExecOptions{})
2024-08-19 22:30:30 +00:00
if err != nil {
2024-08-20 03:23:58 +00:00
return nil, fmt.Errorf("NewSQLite: cannot create schema: %w", err)
2024-08-19 22:30:30 +00:00
}
2024-08-20 03:23:58 +00:00
// err = sqlitex.Execute(conn, createTableFile, &sqlitex.ExecOptions{})
// if err != nil {
// return nil, fmt.Errorf("NewSQLite: cannot create table: %w", err)
// }
// err = sqlitex.Execute(conn, createViewFile, &sqlitex.ExecOptions{})
// if err != nil {
// return nil, fmt.Errorf("NewSQLite: cannot create view: %w", err)
// }
2024-08-19 22:30:30 +00:00
return &SQLiteEmitter{
conn: conn,
}, nil
}
2024-08-20 03:23:58 +00:00
func (s *SQLiteEmitter) Emit(tablePrefix string) func(r Result) error {
query := fmt.Sprintf("INSERT INTO %sresult_raw(expected, actual) VALUES (?, ?)", tablePrefix)
return func(r Result) error {
return sqlitex.Execute(s.conn, query, &sqlitex.ExecOptions{
Args: []any{r.Expected, r.Actual},
})
}
2024-08-19 22:30:30 +00:00
}
2024-08-20 03:23:58 +00:00
func createFile(dir, pattern string) (path string, err error) {
f, err := os.CreateTemp(dir, pattern)
2024-08-19 22:30:30 +00:00
if err != nil {
2024-08-20 03:23:58 +00:00
return "", err
2024-08-19 22:30:30 +00:00
}
2024-08-20 03:23:58 +00:00
f.Close()
return f.Name(), nil
2024-08-19 22:30:30 +00:00
}
2024-08-20 03:23:58 +00:00
func getData(create func(string, string) (string, error), emit func(Result) error) (err error) {
path, err := create("", "go-perm-test-*")
2024-08-19 22:30:30 +00:00
if err != nil {
return err
}
for mode := fs.FileMode(0); mode <= os.ModePerm; mode++ {
err := os.Chmod(path, mode)
if err != nil {
return fmt.Errorf("cannot set mode 0%03o on %s: %w", mode, path, err)
}
info, err := os.Stat(path)
if err != nil {
return fmt.Errorf("cannot stat %s: %w", path, err)
}
result := Result{
Expected: mode,
Actual: info.Mode(),
}
err = emit(result)
if err != nil {
return err
}
}
return nil
}
func run() error {
if len(os.Args) < 2 {
2024-08-20 03:23:58 +00:00
fmt.Fprintf(os.Stderr, "usage: %s <filename>", os.Args[0])
2024-08-19 22:30:30 +00:00
}
2024-08-20 03:23:58 +00:00
dbPath := os.Args[1]
db, err := NewSQLite(dbPath)
if err != nil {
return err
}
defer db.Close()
return errors.Join(getData(createFile, db.Emit("file_")), getData(os.MkdirTemp, db.Emit("dir_")))
2024-08-19 22:30:30 +00:00
}
func main() {
err := run()
if err != nil {
fmt.Fprintf(os.Stderr, "%s: %s\n", os.Args[0], err)
os.Exit(1)
}
}