sqlarfs

package module
v0.0.0-...-8d3427f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 29, 2024 License: Apache-2.0 Imports: 12 Imported by: 0

README

sqlar - Go libraries for SQLite Archive Files

About SQLite Archive Files

See https://sqlite.org/sqlar.html

Status

v0.2.0 should be production ready.

The implementation of sqlarfs is quite naive so far:

  • the DB is queried on every directory read, almost without caching (v0.2.0 has only a cache for FileInfo of directory entries).
  • file data is entirely read in memory on first read of a file.
  • reading file data is done purely through the SQL layer via the database/sql package. The C implementation of SQLite has a BLOB API but we aren't using it.

So it is not yet recommended for thousands of files (but not yet really tested). Reports of performance issues and use cases are very welcome.

Doc

Package github.com/dolmen-go/sqlar/sqlarfs implements interface io/fs.FS.

Example

Using goeval, serve an SQLAr file at https://localhost:8084/ :

$ go install github.com/dolmen-go/goeval@latest
$ goeval -i net/http -i _=github.com/mattn/go-sqlite3@latest -i github.com/dolmen-go/sqlar/sqlarfs@main 'db,err:=sql.Open("sqlite3","file:"+os.Args[1]+"?mode=ro&immutable=1");if err!=nil{panic(err)};defer db.Close();http.Handle("/",http.FileServer(http.FS(sqlarfs.New(db))));http.ListenAndServe(":8084",nil)' sqlarfs/testdata/dir.sqlar

License

Copyright 2023 Olivier Mengué

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Documentation

Overview

Package sqlarfs provides an implementation of io/fs.FS for SQLite Archive Files via database/sql.

Recall that the schema of an SQLite archive file is:

 CREATE TABLE sqlar(
 name TEXT PRIMARY KEY,  -- name of the file (incl. dirs; dirs w trlg "/" ?)
 mode INT,  -- access permissions
 mtime INT, -- last modif'cn time
 sz INT,    -- original file size
 data BLOB  -- compressed content
);
Example
// Open DB in readonly mode for maximum speed
db, err := sql.Open(sqliteDriver, "file:testdata/simple.sqlar?mode=ro&immutable=1")
if err != nil {
	log.Fatal(err)
}
defer db.Close()

// List files in the archive, recusively
ar := sqlarfs.New(db, sqlarfs.PermOwner)
fs.WalkDir(ar, ".", func(path string, d fs.DirEntry, err error) error {
	if err != nil {
		return err
	}
	info, _ := d.Info()
	fmt.Printf("%s %4d %s  %s\n", info.Mode(), info.Size(), info.ModTime().UTC().Format("_2 Jan 2006 15:04"), info.Name())
	return nil
})

// Dump one file
f, err := ar.Open("foo.txt")
if err != nil {
	log.Fatal(err)
}
defer f.Close()
fmt.Println("foo.txt:")
io.Copy(os.Stdout, f)
Output:

dr-xr-xr-x    0  1 Jan 1970 00:00  .
-rw-r--r--    4 30 Sep 2023 14:51  bar.txt
-rw-r--r--    4 30 Sep 2023 16:14  foo.txt
foo.txt:
Foo

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FS

type FS interface {
	fs.FS
	fs.StatFS
	fs.ReadDirFS
}

FS documents the io/fs interfaces provides by this implementation of io/fs.FS. io/fs.StatFS provides io/fs.FileInfo and io/fs.ReadDirFS provides io/fs.ReadDir (name string) ([]DirEntry, error) .

func New

func New(db *sql.DB, opts ...Option) FS

New returns an instance of io/fs.FS that provides access to the files in an [SQLite Archive File] opened with database/sql.

db is a database/sql handle to the SQLite Archive file. Two drivers are known to work: github.com/mattn/sqlite3 and modernc.org/sqlite.

NOTE: sqlarfs uses caching for the directory structure, and so it assumes that the sqlar table is not modified while browsing the filesystem. So if the sqlar table is modified, create a new instance.

For best performance, open the SQLite DB in read-only, immutable mode:

file:<path>?mode=ro&immutable=1

The default permission mask used to enforce file permissions ('mode' column in the 'sqlar' table) is PermAny.

[SQLite Archive File]: https://sqlite.org/sqlar.html .

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option is an option for New.

Available options: PermOwner, PermGroup, PermOthers, PermAny. .

type PermMask

type PermMask uint32

PermMask is a permission mask for enforcing fs.FileMode permissions (disallow to read files, disallow traversing or listing directories) in an SQLite Archive File.

PermMask is an Option for New. .

const (
	PermOwner  PermMask = 0700
	PermGroup  PermMask = 0070
	PermOthers PermMask = 0007
	// PermAny provides read access (or traverse for directories)
	// to any file that has at least one permission bit for either
	// owner/group/others
	PermAny PermMask = 0777
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL