mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-06 18:18:53 +08:00
108 lines
3.7 KiB
Python
108 lines
3.7 KiB
Python
import logging
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import zipfile
|
|
from io import BytesIO
|
|
from pathlib import Path
|
|
from urllib import request
|
|
|
|
|
|
amalgamation_url = 'https://sqlite.org/2021/sqlite-amalgamation-3360000.zip'
|
|
|
|
# Extension-functions
|
|
# ===================
|
|
# It breaks amalgamation if appended as other extension because it redefines
|
|
# several functions, so build it separately. Note that sql.js registers these
|
|
# extension functions by calling ``registerExtensionFunctions`` itself.
|
|
contrib_functions_url = 'https://sqlite.org/contrib/download/extension-functions.c?get=25'
|
|
|
|
extension_urls = (
|
|
# Miscellaneous extensions
|
|
# ========================
|
|
('https://sqlite.org/src/raw/c6bd5d24?at=series.c', 'sqlite3_series_init'),
|
|
('https://sqlite.org/src/raw/dbfd8543?at=closure.c', 'sqlite3_closure_init'),
|
|
('https://sqlite.org/src/raw/5bb2264c?at=uuid.c', 'sqlite3_uuid_init'),
|
|
('https://sqlite.org/src/raw/5853b0e5?at=regexp.c', 'sqlite3_regexp_init'),
|
|
('https://sqlite.org/src/raw/b9086e22?at=percentile.c', 'sqlite3_percentile_init'),
|
|
('https://sqlite.org/src/raw/09f967dc?at=decimal.c', 'sqlite3_decimal_init'),
|
|
# Third-party extension
|
|
# =====================
|
|
('https://github.com/jakethaw/pivot_vtab/raw/08ab0797/pivot_vtab.c', 'sqlite3_pivotvtab_init'),
|
|
)
|
|
|
|
sqljs_url = 'https://github.com/sql-js/sql.js/archive/refs/tags/v1.5.0.zip'
|
|
|
|
|
|
def _generate_extra_init_c_function(init_function_names):
|
|
auto_ext_calls = '\n'.join([
|
|
'nErr += sqlite3_auto_extension((void*){});'.format(init_fn)
|
|
for init_fn in init_function_names
|
|
])
|
|
return '''
|
|
int extra_init(const char* dummy)
|
|
{
|
|
int nErr = 0;
|
|
%s
|
|
return nErr ? SQLITE_ERROR : SQLITE_OK;
|
|
}
|
|
''' % auto_ext_calls
|
|
|
|
|
|
def _get_amalgamation(tgt: Path):
|
|
logging.info('Downloading and extracting SQLite amalgamation %s', amalgamation_url)
|
|
archive = zipfile.ZipFile(BytesIO(request.urlopen(amalgamation_url).read()))
|
|
archive_root_dir = zipfile.Path(archive, archive.namelist()[0])
|
|
for zpath in archive_root_dir.iterdir():
|
|
with zpath.open() as fr, (tgt / zpath.name).open('wb') as fw:
|
|
shutil.copyfileobj(fr, fw)
|
|
|
|
|
|
def _get_contrib_functions(tgt: Path):
|
|
request.urlretrieve(contrib_functions_url, tgt / 'extension-functions.c')
|
|
|
|
|
|
def _get_extensions(tgt: Path):
|
|
init_functions = []
|
|
sqlite3_c = tgt / 'sqlite3.c'
|
|
with sqlite3_c.open('ab') as f:
|
|
for url, init_fn in extension_urls:
|
|
logging.info('Downloading and appending to amalgamation %s', url)
|
|
with request.urlopen(url) as resp:
|
|
shutil.copyfileobj(resp, f)
|
|
init_functions.append(init_fn)
|
|
|
|
logging.info('Appending SQLITE_EXTRA_INIT to amalgamation')
|
|
f.write(_generate_extra_init_c_function(init_functions).encode())
|
|
|
|
|
|
def _get_sqljs(tgt: Path):
|
|
logging.info('Downloading and extracting sql.js %s', sqljs_url)
|
|
archive = zipfile.ZipFile(BytesIO(request.urlopen(sqljs_url).read()))
|
|
archive_root_dir = zipfile.Path(archive, archive.namelist()[0])
|
|
(tgt / 'sqljs').mkdir()
|
|
for zpath in (archive_root_dir / 'src').iterdir():
|
|
with zpath.open() as fr, (tgt / 'sqljs' / zpath.name).open('wb') as fw:
|
|
shutil.copyfileobj(fr, fw)
|
|
|
|
|
|
def configure(tgt: Path):
|
|
_get_amalgamation(tgt)
|
|
_get_contrib_functions(tgt)
|
|
_get_extensions(tgt)
|
|
_get_sqljs(tgt)
|
|
|
|
subprocess.check_call(['emcc', '--version'])
|
|
|
|
|
|
if __name__ == '__main__':
|
|
if sys.version_info < (3, 8):
|
|
print('Python 3.8 or higher is expected', file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
logging.basicConfig(level='INFO', format='%(asctime)s %(levelname)s %(name)s %(message)s')
|
|
|
|
src = Path('src')
|
|
src.mkdir()
|
|
configure(src)
|