mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-07 17:14:09 +02:00
insert-files: add --sqlar flag and content_sqlar column for sqlar-compatible compressed payloads
Adds a --sqlar option that defaults insert-files to the name/mode/mtime/sz/data schema used by SQLite's own sqlar archive format, plus a content_sqlar column type that zlib-compresses content the same way sqlar_compress() does (only when compression actually shrinks the data). Reuses the existing -c coldef parsing added for fixed-literal metadata columns, no changes needed there. Existing BLOB/TEXT content/content_text imports are untouched. Closes #141
This commit is contained in:
parent
6a2e941863
commit
daf2ebbbaf
3 changed files with 91 additions and 2 deletions
|
|
@ -11,6 +11,7 @@ import pathlib
|
|||
import pdb # noqa: T100
|
||||
import sys
|
||||
import textwrap
|
||||
import zlib
|
||||
from datetime import datetime, timezone
|
||||
from runpy import run_module
|
||||
from typing import Any
|
||||
|
|
@ -2913,6 +2914,11 @@ def extract(
|
|||
@click.option("--upsert", is_flag=True, help="Upsert files with matching primary key")
|
||||
@click.option("--name", type=str, help="File name to use")
|
||||
@click.option("--text", is_flag=True, help="Store file content as TEXT, not BLOB")
|
||||
@click.option(
|
||||
"--sqlar",
|
||||
is_flag=True,
|
||||
help="Store file content zlib-compressed, compatible with SQLite's sqlar format",
|
||||
)
|
||||
@click.option(
|
||||
"--encoding",
|
||||
help="Character encoding for input, defaults to utf-8",
|
||||
|
|
@ -2930,6 +2936,7 @@ def insert_files(
|
|||
upsert,
|
||||
name,
|
||||
text,
|
||||
sqlar,
|
||||
encoding,
|
||||
silent,
|
||||
load_extension,
|
||||
|
|
@ -2949,13 +2956,23 @@ def insert_files(
|
|||
-c size:size \\
|
||||
--pk name
|
||||
"""
|
||||
if text and sqlar:
|
||||
raise click.ClickException("Cannot use --text and --sqlar together")
|
||||
if not column:
|
||||
if text:
|
||||
column = ["path:path", "content_text:content_text", "size:size"]
|
||||
elif sqlar:
|
||||
column = [
|
||||
"name:name",
|
||||
"mode:mode",
|
||||
"mtime:mtime_int",
|
||||
"sz:size",
|
||||
"data:content_sqlar",
|
||||
]
|
||||
else:
|
||||
column = ["path:path", "content:content", "size:size"]
|
||||
if not pks:
|
||||
pks = ["path"]
|
||||
pks = ["name"] if sqlar else ["path"]
|
||||
|
||||
def yield_paths_and_relative_paths():
|
||||
for f_or_d in file_or_dir:
|
||||
|
|
@ -2997,6 +3014,9 @@ def insert_files(
|
|||
"content_text": lambda p, data=stdin_data: data.decode(
|
||||
encoding or "utf-8"
|
||||
),
|
||||
"content_sqlar": lambda p, data=stdin_data: sqlar_compress(
|
||||
data
|
||||
),
|
||||
"sha256": lambda p, data=stdin_data: hashlib.sha256(
|
||||
data
|
||||
).hexdigest(),
|
||||
|
|
@ -3688,6 +3708,14 @@ class UnicodeDecodeErrorForPath(Exception):
|
|||
self.path = path
|
||||
|
||||
|
||||
def sqlar_compress(data):
|
||||
# Matches SQLite's sqlar_compress(): use the zlib-compressed blob only
|
||||
# if it is actually smaller than the original, otherwise store as-is.
|
||||
# https://sqlite.org/sqlar.html
|
||||
compressed = zlib.compress(data)
|
||||
return compressed if len(compressed) < len(data) else data
|
||||
|
||||
|
||||
FILE_COLUMNS = {
|
||||
"name": lambda p: p.name,
|
||||
"path": lambda p: str(p),
|
||||
|
|
@ -3696,6 +3724,7 @@ FILE_COLUMNS = {
|
|||
"md5": lambda p: hashlib.md5(p.resolve().read_bytes()).hexdigest(),
|
||||
"mode": lambda p: p.stat().st_mode,
|
||||
"content": lambda p: p.resolve().read_bytes(),
|
||||
"content_sqlar": lambda p: sqlar_compress(p.resolve().read_bytes()),
|
||||
"mtime": lambda p: p.stat().st_mtime,
|
||||
"ctime": lambda p: p.stat().st_ctime,
|
||||
"mtime_int": lambda p: int(p.stat().st_mtime),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue