mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-06 10:08:52 +08:00
* Build SQLite 3.50.3 * Update pivot_vtab, base in Dockerfile.test, fix test after SQLite 3.47 * Update CI image for tests
151 lines
5.7 KiB
Python
151 lines
5.7 KiB
Python
import logging
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import tarfile
|
|
import zipfile
|
|
from io import BytesIO
|
|
from pathlib import Path
|
|
from urllib import request
|
|
|
|
|
|
amalgamation_url = 'https://sqlite.org/2025/sqlite-amalgamation-3500300.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/e212edb2?at=series.c', 'sqlite3_series_init'),
|
|
('https://sqlite.org/src/raw/5559daf1?at=closure.c', 'sqlite3_closure_init'),
|
|
('https://sqlite.org/src/raw/5bb2264c?at=uuid.c', 'sqlite3_uuid_init'),
|
|
('https://sqlite.org/src/raw/388e7f23?at=regexp.c', 'sqlite3_regexp_init'),
|
|
('https://sqlite.org/src/raw/72e05a21?at=percentile.c', 'sqlite3_percentile_init'),
|
|
('https://sqlite.org/src/raw/228d47e9?at=decimal.c', 'sqlite3_decimal_init'),
|
|
# Third-party extension
|
|
# =====================
|
|
('https://github.com/jakethaw/pivot_vtab/raw/e7705f34/pivot_vtab.c', 'sqlite3_pivotvtab_init'),
|
|
('https://github.com/nalgeon/sqlean/raw/95e8d21a/src/pearson.c', 'sqlite3_pearson_init'),
|
|
# Third-party extension with own dependencies
|
|
# ===========================================
|
|
('https://github.com/kev82/sqlitelua/raw/db479510/src/main.c', 'sqlite3_luafunctions_init'),
|
|
)
|
|
|
|
lua_url = 'http://www.lua.org/ftp/lua-5.3.5.tar.gz'
|
|
sqlitelua_url = 'https://github.com/kev82/sqlitelua/archive/db479510.zip'
|
|
|
|
sqljs_url = 'https://github.com/sql-js/sql.js/archive/refs/tags/v1.7.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_lua(tgt: Path):
|
|
# Library definitions from lua/Makefile
|
|
lib_str = '''
|
|
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
|
|
lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
|
|
ltm.o lundump.o lvm.o lzio.o
|
|
LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
|
|
lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o
|
|
LUA_O= lua.o
|
|
'''
|
|
header_only_files = {'lprefix', 'luaconf', 'llimits', 'lualib'}
|
|
lib_names = set(re.findall(r'(\w+)\.o', lib_str)) | header_only_files
|
|
|
|
logging.info('Downloading and extracting Lua %s', lua_url)
|
|
archive = tarfile.open(fileobj=BytesIO(request.urlopen(lua_url).read()))
|
|
(tgt / 'lua').mkdir()
|
|
for tarinfo in archive:
|
|
tarpath = Path(tarinfo.name)
|
|
if tarpath.match('src/*') and tarpath.stem in lib_names:
|
|
with (tgt / 'lua' / tarpath.name).open('wb') as fw:
|
|
shutil.copyfileobj(archive.extractfile(tarinfo), fw)
|
|
|
|
logging.info('Downloading and extracting SQLite Lua extension %s', sqlitelua_url)
|
|
archive = zipfile.ZipFile(BytesIO(request.urlopen(sqlitelua_url).read()))
|
|
archive_root_dir = zipfile.Path(archive, archive.namelist()[0])
|
|
(tgt / 'sqlitelua').mkdir()
|
|
for zpath in (archive_root_dir / 'src').iterdir():
|
|
if zpath.name != 'main.c':
|
|
with zpath.open() as fr, (tgt / 'sqlitelua' / 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:
|
|
f.write(b'\n')
|
|
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_lua(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)
|