setta 0.0.1.dev0__py3-none-any.whl → 0.0.2.dev0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- setta/__init__.py +1 -1
- setta/cli/__init__.py +1 -0
- setta/cli/connect.py +43 -0
- setta/cli/logger.py +225 -0
- setta/code_gen/__init__.py +0 -0
- setta/code_gen/create_runnable_scripts.py +466 -0
- setta/code_gen/export_selected.py +776 -0
- setta/code_gen/find_placeholders.py +13 -0
- setta/code_gen/python/__init__.py +0 -0
- setta/code_gen/python/ast_utils.py +183 -0
- setta/code_gen/python/check_scope.py +187 -0
- setta/code_gen/python/generate_code.py +280 -0
- setta/code_gen/python/make_parseable.py +97 -0
- setta/code_gen/python/position_line_col.py +33 -0
- setta/code_gen/python/validate_imports.py +87 -0
- setta/code_gen/utils.py +120 -0
- setta/code_gen/yaml/__init__.py +0 -0
- setta/code_gen/yaml/generate_yaml.py +23 -0
- setta/code_gen/yaml/section_dict.py +93 -0
- setta/database/__init__.py +0 -0
- setta/database/backup.py +80 -0
- setta/database/db/__init__.py +0 -0
- setta/database/db/artifacts/__init__.py +0 -0
- setta/database/db/artifacts/load.py +93 -0
- setta/database/db/artifacts/save.py +85 -0
- setta/database/db/artifacts/save_or_create.py +68 -0
- setta/database/db/artifacts/utils.py +13 -0
- setta/database/db/codeInfo/__init__.py +0 -0
- setta/database/db/codeInfo/copy.py +26 -0
- setta/database/db/codeInfo/load.py +65 -0
- setta/database/db/codeInfo/save.py +75 -0
- setta/database/db/codeInfo/utils.py +33 -0
- setta/database/db/evRefs/__init__.py +0 -0
- setta/database/db/evRefs/load.py +45 -0
- setta/database/db/evRefs/save.py +95 -0
- setta/database/db/projects/__init__.py +0 -0
- setta/database/db/projects/copy.py +36 -0
- setta/database/db/projects/delete.py +7 -0
- setta/database/db/projects/load.py +184 -0
- setta/database/db/projects/save.py +267 -0
- setta/database/db/projects/saveAs.py +40 -0
- setta/database/db/projects/utils.py +135 -0
- setta/database/db/sectionVariants/__init__.py +0 -0
- setta/database/db/sectionVariants/copy.py +28 -0
- setta/database/db/sectionVariants/load.py +139 -0
- setta/database/db/sectionVariants/save.py +140 -0
- setta/database/db/sectionVariants/utils.py +44 -0
- setta/database/db/sections/__init__.py +0 -0
- setta/database/db/sections/copy.py +70 -0
- setta/database/db/sections/jsonSource.py +119 -0
- setta/database/db/sections/load.py +350 -0
- setta/database/db/sections/save.py +204 -0
- setta/database/db/sections/utils.py +13 -0
- setta/database/db/uiTypes/__init__.py +0 -0
- setta/database/db/uiTypes/copy.py +33 -0
- setta/database/db/uiTypes/load.py +51 -0
- setta/database/db/uiTypes/save.py +99 -0
- setta/database/db/uiTypes/utils.py +27 -0
- setta/database/db_init.py +36 -0
- setta/database/db_objs.py +102 -0
- setta/database/db_path.py +8 -0
- setta/database/export_db/__init__.py +0 -0
- setta/database/export_db/export_db.py +43 -0
- setta/database/export_db/export_raw.py +53 -0
- setta/database/export_db/export_readable.py +242 -0
- setta/database/export_db/utils.py +16 -0
- setta/database/import_db.py +28 -0
- setta/database/seed.py +41 -0
- setta/database/settings_file.py +118 -0
- setta/database/utils.py +32 -0
- setta/lsp/__init__.py +0 -0
- setta/lsp/file_watcher.py +113 -0
- setta/lsp/reader.py +184 -0
- setta/lsp/reader_fns/__init__.py +0 -0
- setta/lsp/reader_fns/completion.py +84 -0
- setta/lsp/reader_fns/definition.py +2 -0
- setta/lsp/reader_fns/diagnostics.py +99 -0
- setta/lsp/reader_fns/documentHighlight.py +25 -0
- setta/lsp/reader_fns/references.py +34 -0
- setta/lsp/reader_fns/signatureHelp.py +99 -0
- setta/lsp/server.py +150 -0
- setta/lsp/utils.py +60 -0
- setta/lsp/writer.py +306 -0
- setta/routers/__init__.py +11 -0
- setta/routers/artifact.py +105 -0
- setta/routers/code_info.py +32 -0
- setta/routers/dependencies.py +49 -0
- setta/routers/in_memory_fn_stdout_websocket.py +21 -0
- setta/routers/interactive.py +119 -0
- setta/routers/lsp.py +14 -0
- setta/routers/projects.py +188 -0
- setta/routers/reference_renaming.py +111 -0
- setta/routers/sections.py +174 -0
- setta/routers/settings.py +40 -0
- setta/routers/terminals.py +83 -0
- setta/routers/websocket.py +36 -0
- setta/server.py +141 -0
- setta/start.py +112 -0
- setta/static/constants/BaseUITypes.json +153 -0
- setta/static/constants/Settings.json +113 -0
- setta/static/constants/constants.json +117 -0
- setta/static/constants/db_init.sql +249 -0
- setta/static/constants/defaultValues.json +125 -0
- setta/static/constants/settingsProject.json +276 -0
- setta/static/frontend/android-chrome-192x192.png +0 -0
- setta/static/frontend/android-chrome-512x512.png +0 -0
- setta/static/frontend/apple-touch-icon.png +0 -0
- setta/static/frontend/assets/KaTeX_AMS-Regular-0cdd387c.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_AMS-Regular-30da91e8.woff +0 -0
- setta/static/frontend/assets/KaTeX_AMS-Regular-68534840.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Bold-07d8e303.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Bold-1ae6bd74.woff +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Bold-de7701e4.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Regular-3398dd02.woff +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Regular-5d53e70a.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Regular-ed0b7437.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Bold-74444efd.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Bold-9163df9c.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Bold-9be7ceb8.woff +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Regular-1e6f9579.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Regular-51814d27.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Regular-5e28753b.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Bold-0f60d1b8.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-Bold-138ac28d.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Main-Bold-c76c5d69.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-BoldItalic-70ee1f64.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Main-BoldItalic-99cd42a3.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-BoldItalic-a6f7ec0d.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Italic-0d85ae7c.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Main-Italic-97479ca6.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-Italic-f1d6ef86.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Regular-c2342cd8.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-Regular-c6368d87.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Regular-d0332f52.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Math-BoldItalic-850c0af5.woff +0 -0
- setta/static/frontend/assets/KaTeX_Math-BoldItalic-dc47344d.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Math-BoldItalic-f9377ab0.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Math-Italic-08ce98e5.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Math-Italic-7af58c5e.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Math-Italic-8a8d2445.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Bold-1ece03f7.ttf +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Bold-e99ae511.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Bold-ece03cfd.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Italic-00b26ac8.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Italic-3931dd81.ttf +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Italic-91ee6750.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Regular-11e4dc8a.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Regular-68e8c73e.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Regular-f36ea897.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Script-Regular-036d4e95.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Script-Regular-1c67f068.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Script-Regular-d96cdf2b.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size1-Regular-6b47c401.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Size1-Regular-95b6d2f1.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Size1-Regular-c943cc98.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size2-Regular-2014c523.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size2-Regular-a6b2099f.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Size2-Regular-d04c5421.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Size3-Regular-500e04d5.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Size3-Regular-6ab6b62e.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size4-Regular-99f9c675.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size4-Regular-a4af7d41.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Size4-Regular-c647367d.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Typewriter-Regular-71d517d6.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Typewriter-Regular-e14fed02.woff +0 -0
- setta/static/frontend/assets/KaTeX_Typewriter-Regular-f01f3e87.ttf +0 -0
- setta/static/frontend/assets/cormorant-garamond-all-700-italic-c9b58582.woff +0 -0
- setta/static/frontend/assets/cormorant-garamond-cyrillic-700-italic-9101ad5f.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-cyrillic-ext-700-italic-950de0d6.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-latin-700-italic-0bc53e12.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-latin-ext-700-italic-525738e0.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-vietnamese-700-italic-99563037.woff2 +0 -0
- setta/static/frontend/assets/erase-5e0448ea.svg +15 -0
- setta/static/frontend/assets/index-1d4b4ecf.css +32 -0
- setta/static/frontend/assets/index-ee99dc72.js +678 -0
- setta/static/frontend/assets/inter-all-400-normal-054f12d0.woff +0 -0
- setta/static/frontend/assets/inter-all-600-normal-c03769e5.woff +0 -0
- setta/static/frontend/assets/inter-all-800-normal-15dc6e4b.woff +0 -0
- setta/static/frontend/assets/inter-cyrillic-400-normal-a4eee61a.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-600-normal-8b14f703.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-800-normal-e706eaaa.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-ext-400-normal-70047a3b.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-ext-600-normal-d4ab9bc4.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-ext-800-normal-eae7515a.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-400-normal-381ea30d.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-600-normal-601f93a2.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-800-normal-7af4fb64.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-ext-400-normal-27027b17.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-ext-600-normal-f2ddf9de.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-ext-800-normal-4cb6189e.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-400-normal-d56fec21.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-600-normal-ff769fa6.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-800-normal-5eea1309.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-ext-400-normal-bb698d85.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-ext-600-normal-ca4808f9.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-ext-800-normal-ebdacc0f.woff2 +0 -0
- setta/static/frontend/assets/logo/logo.svg +8 -0
- setta/static/frontend/assets/pen-455d7d8a.svg +19 -0
- setta/static/frontend/assets/source-code-pro-all-500-normal-6bdaa03b.woff +0 -0
- setta/static/frontend/assets/source-code-pro-cyrillic-500-normal-288a0d68.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-cyrillic-ext-500-normal-b110a13b.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-greek-500-normal-04328acb.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-latin-500-normal-06edef1e.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-latin-ext-500-normal-6dc60d5e.woff2 +0 -0
- setta/static/frontend/assets/web-vitals-44a8e082.js +1 -0
- setta/static/frontend/assets/work-sans-all-400-normal-38034a3c.woff +0 -0
- setta/static/frontend/assets/work-sans-all-500-normal-550d64e5.woff +0 -0
- setta/static/frontend/assets/work-sans-all-600-normal-ccf14060.woff +0 -0
- setta/static/frontend/assets/work-sans-all-700-normal-494c2971.woff +0 -0
- setta/static/frontend/assets/work-sans-latin-400-normal-36735bc1.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-500-normal-3790bfda.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-600-normal-5fba494e.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-700-normal-a5033d0a.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-400-normal-c20f571a.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-500-normal-0f5ac96c.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-600-normal-97a237d1.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-700-normal-103e112c.woff2 +0 -0
- setta/static/frontend/browserconfig.xml +9 -0
- setta/static/frontend/favicon-16x16.png +0 -0
- setta/static/frontend/favicon-32x32.png +0 -0
- setta/static/frontend/favicon.ico +0 -0
- setta/static/frontend/index.html +30 -0
- setta/static/frontend/manifest.json +25 -0
- setta/static/frontend/mstile-144x144.png +0 -0
- setta/static/frontend/mstile-150x150.png +0 -0
- setta/static/frontend/mstile-310x150.png +0 -0
- setta/static/frontend/mstile-310x310.png +0 -0
- setta/static/frontend/mstile-70x70.png +0 -0
- setta/static/frontend/robots.txt +3 -0
- setta/static/frontend/safari-pinned-tab.svg +18 -0
- setta/static/frontend/site.webmanifest +19 -0
- setta/static/seed/.DS_Store +0 -0
- setta/static/seed/examples/.DS_Store +0 -0
- setta/tasks/__init__.py +0 -0
- setta/tasks/fns/__init__.py +9 -0
- setta/tasks/fns/codeAreaAutocomplete.py +209 -0
- setta/tasks/fns/codeAreaFindTemplateVars.py +128 -0
- setta/tasks/fns/codeAreaInitializeCode.py +98 -0
- setta/tasks/fns/findEVRefs.py +236 -0
- setta/tasks/fns/parametersRequest.py +71 -0
- setta/tasks/fns/textFieldAutocomplete.py +210 -0
- setta/tasks/fns/textFieldInitializeCode.py +99 -0
- setta/tasks/fns/typeCheck.py +40 -0
- setta/tasks/fns/utils.py +134 -0
- setta/tasks/task_runner.py +29 -0
- setta/tasks/tasks.py +152 -0
- setta/tasks/utils.py +178 -0
- setta/terminals/__init__.py +0 -0
- setta/terminals/terminals.py +242 -0
- setta/terminals/utils.py +37 -0
- setta/utils/__init__.py +0 -0
- setta/utils/constants.py +148 -0
- setta/utils/generate_memorable_string.py +431 -0
- setta/utils/generate_new_filename.py +80 -0
- setta/utils/section_contents.py +133 -0
- setta/utils/utils.py +271 -0
- setta/utils/websocket_manager.py +91 -0
- setta-0.0.2.dev0.dist-info/LICENSE +201 -0
- setta-0.0.2.dev0.dist-info/METADATA +24 -0
- setta-0.0.2.dev0.dist-info/RECORD +263 -0
- {setta-0.0.1.dev0.dist-info → setta-0.0.2.dev0.dist-info}/WHEEL +1 -1
- setta-0.0.2.dev0.dist-info/entry_points.txt +2 -0
- setta-0.0.1.dev0.dist-info/METADATA +0 -18
- setta-0.0.1.dev0.dist-info/RECORD +0 -5
- {setta-0.0.1.dev0.dist-info → setta-0.0.2.dev0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
import json
|
2
|
+
|
3
|
+
from setta.utils.constants import DEFAULT_VALUES, UI_TYPE_TABLE_DATA_JSON_FIELDS
|
4
|
+
from setta.utils.utils import filter_dict
|
5
|
+
|
6
|
+
|
7
|
+
def save_ui_types(db, uiTypes):
|
8
|
+
query = """
|
9
|
+
INSERT INTO UIType (id, type, data)
|
10
|
+
VALUES (:id, :type, :data)
|
11
|
+
ON CONFLICT (id)
|
12
|
+
DO UPDATE SET
|
13
|
+
type = :type,
|
14
|
+
data = :data
|
15
|
+
"""
|
16
|
+
|
17
|
+
query_parameters = [
|
18
|
+
{
|
19
|
+
"id": v["id"],
|
20
|
+
"type": v["type"],
|
21
|
+
"data": json.dumps(
|
22
|
+
filter_dict(v, UI_TYPE_TABLE_DATA_JSON_FIELDS, DEFAULT_VALUES["uiType"])
|
23
|
+
),
|
24
|
+
}
|
25
|
+
for v in uiTypes.values()
|
26
|
+
]
|
27
|
+
db.executemany(query, query_parameters)
|
28
|
+
|
29
|
+
|
30
|
+
def save_ui_type_cols(db, uitype_cols):
|
31
|
+
query = """
|
32
|
+
INSERT INTO UITypeColId (id)
|
33
|
+
VALUES (:id)
|
34
|
+
ON CONFLICT (id)
|
35
|
+
DO NOTHING
|
36
|
+
"""
|
37
|
+
|
38
|
+
query_params = [{"id": k} for k in uitype_cols.keys()]
|
39
|
+
db.executemany(query, query_params)
|
40
|
+
|
41
|
+
query_params = []
|
42
|
+
for idid in uitype_cols.keys():
|
43
|
+
for code_info_id in uitype_cols[idid].keys():
|
44
|
+
query_params.extend([idid, code_info_id])
|
45
|
+
placeholders = ", ".join(["(?, ?)"] * (len(query_params) // 2))
|
46
|
+
query = f"""
|
47
|
+
UPDATE UIType
|
48
|
+
SET asNonPresetForUITypeColId = null,
|
49
|
+
asNonPresetForCodeInfoId = null
|
50
|
+
WHERE (asNonPresetForUITypeColId, asNonPresetForCodeInfoId) IN ({placeholders})
|
51
|
+
"""
|
52
|
+
db.execute(query, query_params)
|
53
|
+
|
54
|
+
placeholders = ", ".join(["?"] * len(uitype_cols))
|
55
|
+
query = f"""
|
56
|
+
DELETE FROM UITypeCol
|
57
|
+
WHERE idid IN ({placeholders})
|
58
|
+
"""
|
59
|
+
query_params = list(uitype_cols.keys())
|
60
|
+
db.execute(query, query_params)
|
61
|
+
|
62
|
+
query = """
|
63
|
+
INSERT INTO UITypeCol (idid, codeInfoId, uiTypeId)
|
64
|
+
VALUES (:idid, :codeInfoId, :uiTypeId)
|
65
|
+
"""
|
66
|
+
query_params = []
|
67
|
+
for idid in uitype_cols.keys():
|
68
|
+
for code_info_id, ui_info in uitype_cols[idid].items():
|
69
|
+
query_params.append(
|
70
|
+
{
|
71
|
+
"idid": idid,
|
72
|
+
"codeInfoId": code_info_id,
|
73
|
+
"uiTypeId": ui_info["uiTypeId"],
|
74
|
+
}
|
75
|
+
)
|
76
|
+
|
77
|
+
db.executemany(query, query_params)
|
78
|
+
|
79
|
+
query = """
|
80
|
+
UPDATE UIType
|
81
|
+
SET asNonPresetForUITypeColId = :uiTypeColId,
|
82
|
+
asNonPresetForCodeInfoId = :codeInfoId
|
83
|
+
WHERE id = :nonPresetUITypeId
|
84
|
+
"""
|
85
|
+
query_params = []
|
86
|
+
for idid in uitype_cols.keys():
|
87
|
+
for code_info_id, ui_info in uitype_cols[idid].items():
|
88
|
+
query_params.extend(
|
89
|
+
[
|
90
|
+
{
|
91
|
+
"uiTypeColId": idid,
|
92
|
+
"codeInfoId": code_info_id,
|
93
|
+
"nonPresetUITypeId": x,
|
94
|
+
}
|
95
|
+
for x in ui_info["nonPresetUITypeIds"]
|
96
|
+
]
|
97
|
+
)
|
98
|
+
|
99
|
+
db.executemany(query, query_params)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import copy
|
2
|
+
|
3
|
+
from setta.utils.constants import DEFAULT_VALUES
|
4
|
+
from setta.utils.utils import recursive_dict_merge
|
5
|
+
|
6
|
+
|
7
|
+
def add_defaults_to_ui_types(ui_types):
|
8
|
+
for id in ui_types.keys():
|
9
|
+
ui_types[id] = with_ui_type_defaults(**ui_types[id])
|
10
|
+
|
11
|
+
|
12
|
+
def with_ui_type_defaults(**kwargs):
|
13
|
+
return recursive_dict_merge(copy.deepcopy(DEFAULT_VALUES["uiType"]), kwargs)
|
14
|
+
|
15
|
+
|
16
|
+
def new_ui_type_col_entry():
|
17
|
+
return copy.deepcopy(DEFAULT_VALUES["uiTypeColEntry"])
|
18
|
+
|
19
|
+
|
20
|
+
def add_defaults_to_ui_type_cols(ui_type_cols):
|
21
|
+
for v in ui_type_cols.values():
|
22
|
+
for paramId in v.keys():
|
23
|
+
v[paramId] = with_ui_type_col_entry_defaults(**v[paramId])
|
24
|
+
|
25
|
+
|
26
|
+
def with_ui_type_col_entry_defaults(**kwargs):
|
27
|
+
return recursive_dict_merge(copy.deepcopy(DEFAULT_VALUES["uiTypeColEntry"]), kwargs)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
from setta.utils.constants import CONSTANTS_FOLDER
|
2
|
+
from setta.utils.utils import get_absolute_path
|
3
|
+
|
4
|
+
from .seed import seed
|
5
|
+
|
6
|
+
|
7
|
+
def create_tables(db):
|
8
|
+
with open(
|
9
|
+
get_absolute_path(__file__, CONSTANTS_FOLDER / "db_init.sql"), "r"
|
10
|
+
) as sql_file:
|
11
|
+
sql_script = sql_file.read()
|
12
|
+
db.executescript(sql_script)
|
13
|
+
|
14
|
+
|
15
|
+
def seed_data_exist(db, tablenames):
|
16
|
+
for table in tablenames:
|
17
|
+
db.execute(f"SELECT COUNT(*) FROM {table}")
|
18
|
+
if db.fetchone()[0] == 0:
|
19
|
+
return False
|
20
|
+
return True
|
21
|
+
|
22
|
+
|
23
|
+
def maybe_create_tables_and_seed(dbq, with_examples=False, with_base_ui_types=True):
|
24
|
+
dbq.connect()
|
25
|
+
with dbq as db:
|
26
|
+
create_tables(db)
|
27
|
+
do_seed_examples = with_examples and not seed_data_exist(db, ["ProjectConfig"])
|
28
|
+
do_seed_base_ui_types = with_base_ui_types and not seed_data_exist(
|
29
|
+
db, ["UIType"]
|
30
|
+
)
|
31
|
+
seed(
|
32
|
+
db,
|
33
|
+
with_examples=do_seed_examples,
|
34
|
+
with_base_ui_types=do_seed_base_ui_types,
|
35
|
+
)
|
36
|
+
dbq.disconnect()
|
@@ -0,0 +1,102 @@
|
|
1
|
+
import queue
|
2
|
+
import sqlite3
|
3
|
+
|
4
|
+
|
5
|
+
class DB:
|
6
|
+
def __init__(self, path):
|
7
|
+
self.conn = None
|
8
|
+
self.cursor = None
|
9
|
+
self.path = path
|
10
|
+
|
11
|
+
def connect(self):
|
12
|
+
if not self.conn:
|
13
|
+
self.conn = sqlite3.connect(
|
14
|
+
self.path,
|
15
|
+
check_same_thread=False,
|
16
|
+
)
|
17
|
+
self.conn.row_factory = sqlite3.Row
|
18
|
+
self.cursor = self.conn.cursor()
|
19
|
+
self.execute("PRAGMA foreign_keys = ON;")
|
20
|
+
|
21
|
+
def disconnect(self):
|
22
|
+
if self.conn:
|
23
|
+
self.cursor.close()
|
24
|
+
self.conn.close()
|
25
|
+
self.cursor = None
|
26
|
+
self.conn = None
|
27
|
+
|
28
|
+
def commit(self):
|
29
|
+
self.conn.commit()
|
30
|
+
|
31
|
+
def rollback(self):
|
32
|
+
self.conn.rollback()
|
33
|
+
|
34
|
+
def execute(self, *args, **kwargs):
|
35
|
+
self.cursor.execute(*args, **kwargs)
|
36
|
+
|
37
|
+
def executemany(self, *args, **kwargs):
|
38
|
+
self.cursor.executemany(*args, **kwargs)
|
39
|
+
|
40
|
+
def executescript(self, *args, **kwargs):
|
41
|
+
self.cursor.executescript(*args, **kwargs)
|
42
|
+
|
43
|
+
def fetchall(self, *args, **kwargs):
|
44
|
+
return self.cursor.fetchall(*args, **kwargs)
|
45
|
+
|
46
|
+
def fetchone(self, *args, **kwargs):
|
47
|
+
return self.cursor.fetchone(*args, **kwargs)
|
48
|
+
|
49
|
+
@property
|
50
|
+
def description(self):
|
51
|
+
return self.cursor.description
|
52
|
+
|
53
|
+
def __enter__(self, *args, **kwargs):
|
54
|
+
self.conn.__enter__(*args, **kwargs)
|
55
|
+
return self
|
56
|
+
|
57
|
+
def __exit__(self, *args, **kwargs):
|
58
|
+
return self.conn.__exit__(*args, **kwargs)
|
59
|
+
|
60
|
+
|
61
|
+
class DBQueue:
|
62
|
+
def __init__(self, path, n=1):
|
63
|
+
self.queue = queue.Queue()
|
64
|
+
for _ in range(n):
|
65
|
+
self.queue.put(DB(path))
|
66
|
+
self.curr = None
|
67
|
+
|
68
|
+
def set_curr(self):
|
69
|
+
self.curr = self.queue.get()
|
70
|
+
|
71
|
+
def put_back_curr(self):
|
72
|
+
self.queue.put(self.curr)
|
73
|
+
self.curr = None
|
74
|
+
|
75
|
+
def process_conns(self, fn_name):
|
76
|
+
all_dbs = []
|
77
|
+
while True:
|
78
|
+
try:
|
79
|
+
db = self.queue.get_nowait()
|
80
|
+
except queue.Empty:
|
81
|
+
break
|
82
|
+
else:
|
83
|
+
fn = getattr(db, fn_name)
|
84
|
+
fn()
|
85
|
+
all_dbs.append(db)
|
86
|
+
|
87
|
+
for db in all_dbs:
|
88
|
+
self.queue.put(db)
|
89
|
+
|
90
|
+
def connect(self):
|
91
|
+
self.process_conns("connect")
|
92
|
+
|
93
|
+
def disconnect(self):
|
94
|
+
self.process_conns("disconnect")
|
95
|
+
|
96
|
+
def __enter__(self, *args, **kwargs):
|
97
|
+
self.set_curr()
|
98
|
+
return self.curr.__enter__(*args, **kwargs)
|
99
|
+
|
100
|
+
def __exit__(self, *args, **kwargs):
|
101
|
+
self.curr.__exit__(*args, **kwargs)
|
102
|
+
self.put_back_curr()
|
File without changes
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from setta.utils.constants import USER_SETTINGS
|
4
|
+
|
5
|
+
from ..db_objs import DBQueue
|
6
|
+
from .export_raw import export_raw
|
7
|
+
from .export_readable import export_readable
|
8
|
+
|
9
|
+
|
10
|
+
def _export_database(
|
11
|
+
db, filename, raw=True, readable=True, readable_with_variants=True
|
12
|
+
):
|
13
|
+
if not raw and not readable and not readable_with_variants:
|
14
|
+
return
|
15
|
+
filename = os.path.splitext(os.path.basename(filename))[0]
|
16
|
+
if raw:
|
17
|
+
export_raw(db, filename)
|
18
|
+
if readable:
|
19
|
+
export_readable(db, filename, with_variants=False)
|
20
|
+
if readable_with_variants:
|
21
|
+
export_readable(db, filename, with_variants=True)
|
22
|
+
|
23
|
+
|
24
|
+
def export_database(path):
|
25
|
+
# Connect to the SQLite database
|
26
|
+
dbq = DBQueue(path)
|
27
|
+
dbq.connect()
|
28
|
+
with dbq as db:
|
29
|
+
# Export the database, including schema and data, to JSON and YAML
|
30
|
+
_export_database(db, path, True, True, True)
|
31
|
+
dbq.disconnect()
|
32
|
+
|
33
|
+
|
34
|
+
def maybe_export_database(db, path):
|
35
|
+
_export_database(
|
36
|
+
db,
|
37
|
+
path,
|
38
|
+
raw=USER_SETTINGS["backend"]["exportDbRawOnSave"],
|
39
|
+
readable=USER_SETTINGS["backend"]["exportDbReadableOnSave"],
|
40
|
+
readable_with_variants=USER_SETTINGS["backend"][
|
41
|
+
"exportDbReadableWithVariantsOnSave"
|
42
|
+
],
|
43
|
+
)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import logging
|
2
|
+
import os
|
3
|
+
from pathlib import Path
|
4
|
+
|
5
|
+
import yaml
|
6
|
+
|
7
|
+
logger = logging.getLogger(__name__)
|
8
|
+
|
9
|
+
|
10
|
+
def export_raw(db, filename):
|
11
|
+
schema = fetch_schema(db)
|
12
|
+
data = fetch_all_data(db)
|
13
|
+
|
14
|
+
# Combined schema and data for JSON export
|
15
|
+
database_export = {"schema": schema, "data": data}
|
16
|
+
|
17
|
+
# with open(f"{filename}_export.json", 'w') as file:
|
18
|
+
# json.dump(database_export, file, indent=4)
|
19
|
+
|
20
|
+
# Customize the YAML dump to use literal style for SQL
|
21
|
+
def literal_presenter(dumper, data):
|
22
|
+
if "\n" in data:
|
23
|
+
return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|")
|
24
|
+
return dumper.represent_scalar("tag:yaml.org,2002:str", data)
|
25
|
+
|
26
|
+
yaml.add_representer(str, literal_presenter)
|
27
|
+
|
28
|
+
# For YAML export, PyYAML is used; ensure it's installed
|
29
|
+
filepath = Path(os.getcwd()) / f"{filename}_export.yaml"
|
30
|
+
logger.debug(f"saving raw db to {filepath}")
|
31
|
+
with open(filepath, "w") as file:
|
32
|
+
yaml.dump(database_export, file, allow_unicode=True, sort_keys=False)
|
33
|
+
|
34
|
+
|
35
|
+
def fetch_schema(cursor):
|
36
|
+
"""Fetch the schema of all tables in the database."""
|
37
|
+
cursor.execute("SELECT type, name, sql FROM sqlite_master WHERE sql NOT NULL;")
|
38
|
+
schema = {}
|
39
|
+
for type, name, sql in cursor.fetchall():
|
40
|
+
if name not in schema:
|
41
|
+
schema[name] = {"type": type, "sql": sql}
|
42
|
+
return schema
|
43
|
+
|
44
|
+
|
45
|
+
def fetch_all_data(cursor):
|
46
|
+
"""Fetch all data from the database."""
|
47
|
+
data = {}
|
48
|
+
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
|
49
|
+
for (table_name,) in cursor.fetchall():
|
50
|
+
cursor.execute(f"SELECT * FROM {table_name}")
|
51
|
+
columns = [description[0] for description in cursor.description]
|
52
|
+
data[table_name] = [dict(zip(columns, row)) for row in cursor.fetchall()]
|
53
|
+
return data
|
@@ -0,0 +1,242 @@
|
|
1
|
+
import logging
|
2
|
+
import os
|
3
|
+
import shutil
|
4
|
+
from pathlib import Path
|
5
|
+
|
6
|
+
from setta.cli.logger import save_base64_to_png
|
7
|
+
from setta.code_gen.export_selected import (
|
8
|
+
export_param_sweep_section_to_dict,
|
9
|
+
export_section_to_dict,
|
10
|
+
export_single_run_group_to_dict,
|
11
|
+
get_for_section_id,
|
12
|
+
get_section_name,
|
13
|
+
get_section_type,
|
14
|
+
get_section_variant_attr,
|
15
|
+
get_section_variant_ids,
|
16
|
+
get_selected_section_variant,
|
17
|
+
get_selected_section_variant_id,
|
18
|
+
get_variant_code,
|
19
|
+
get_variant_name,
|
20
|
+
)
|
21
|
+
from setta.code_gen.yaml.section_dict import (
|
22
|
+
param_sweep_dict_to_yaml,
|
23
|
+
run_group_dict_to_yaml,
|
24
|
+
section_dict_to_yaml,
|
25
|
+
)
|
26
|
+
from setta.database.db.artifacts.load import (
|
27
|
+
load_artifact_metadata_and_maybe_value_from_disk,
|
28
|
+
)
|
29
|
+
from setta.utils.constants import C
|
30
|
+
from setta.utils.section_contents import getParamIdsToShowInArea
|
31
|
+
|
32
|
+
from .utils import get_configs_and_root_folder
|
33
|
+
|
34
|
+
logger = logging.getLogger(__name__)
|
35
|
+
|
36
|
+
|
37
|
+
def export_readable(db, filename, with_variants):
|
38
|
+
configs, root_folder = get_configs_and_root_folder(db, filename)
|
39
|
+
subfolder_name = "with_variants" if with_variants else "clean"
|
40
|
+
root_folder = root_folder / subfolder_name
|
41
|
+
try:
|
42
|
+
logger.debug(f"try deleting: {root_folder}")
|
43
|
+
shutil.rmtree(root_folder)
|
44
|
+
except:
|
45
|
+
pass
|
46
|
+
|
47
|
+
logger.debug(f"exporting readable to {root_folder}")
|
48
|
+
|
49
|
+
artifactIds = set()
|
50
|
+
for c in configs:
|
51
|
+
for ag in c["artifactGroups"].values():
|
52
|
+
for t in ag["artifactTransforms"]:
|
53
|
+
artifactIds.add(t["artifactId"])
|
54
|
+
|
55
|
+
artifacts = load_artifact_metadata_and_maybe_value_from_disk(db, list(artifactIds))
|
56
|
+
|
57
|
+
for c in configs:
|
58
|
+
c["artifacts"] = artifacts
|
59
|
+
export_config(root_folder, c, with_variants)
|
60
|
+
|
61
|
+
|
62
|
+
def export_config(folder, config, with_variants):
|
63
|
+
config_folder = Path(folder) / config["projectConfig"]["name"]
|
64
|
+
for k in config["projectConfig"]["children"].keys():
|
65
|
+
os.makedirs(config_folder, exist_ok=True)
|
66
|
+
export_section(config_folder, config, k, with_variants)
|
67
|
+
|
68
|
+
|
69
|
+
def export_section(folder, config, section_id, with_variants):
|
70
|
+
exporter_fn = get_exporter_fn(config, section_id)
|
71
|
+
if not exporter_fn:
|
72
|
+
return
|
73
|
+
variant_ids = (
|
74
|
+
get_section_variant_ids(config, section_id)
|
75
|
+
if with_variants
|
76
|
+
else [get_selected_section_variant_id(config, section_id)]
|
77
|
+
)
|
78
|
+
for variant_id in variant_ids:
|
79
|
+
if not variant_id:
|
80
|
+
continue
|
81
|
+
exporter_fn(folder, config, section_id, variant_id, with_variants)
|
82
|
+
|
83
|
+
|
84
|
+
def export_code(folder, config, section_id, variant_id, with_variants):
|
85
|
+
codeLanguage = config["sections"][section_id]["codeLanguage"]
|
86
|
+
code = get_variant_code(config, variant_id)
|
87
|
+
base = maybe_with_variant_in_filename(config, section_id, variant_id, with_variants)
|
88
|
+
extension = {"javascript": "js", "python": "py", "bash": "sh"}[codeLanguage]
|
89
|
+
with open(f"{folder / base}.{extension}", "w") as file:
|
90
|
+
file.write(code)
|
91
|
+
|
92
|
+
|
93
|
+
def export_regular_section(folder, config, section_id, variant_id, with_variants):
|
94
|
+
sectionVariant = config["sectionVariants"][variant_id]
|
95
|
+
selectedItemId = sectionVariant["selectedItem"]
|
96
|
+
codeInfoChildren = (
|
97
|
+
config["codeInfoCols"]
|
98
|
+
.get(sectionVariant["codeInfoColId"], {})
|
99
|
+
.get("children", {})
|
100
|
+
)
|
101
|
+
pinned = getParamIdsToShowInArea(
|
102
|
+
True,
|
103
|
+
config["codeInfo"],
|
104
|
+
codeInfoChildren,
|
105
|
+
selectedItemId,
|
106
|
+
)
|
107
|
+
unpinned = getParamIdsToShowInArea(
|
108
|
+
False,
|
109
|
+
config["codeInfo"],
|
110
|
+
codeInfoChildren,
|
111
|
+
selectedItemId,
|
112
|
+
)
|
113
|
+
pinned["requiredParamIds"] = pinned["requiredParamIdsToPaths"].keys()
|
114
|
+
unpinned["requiredParamIds"] = unpinned["requiredParamIdsToPaths"].keys()
|
115
|
+
del pinned["requiredParamIdsToPaths"]
|
116
|
+
del unpinned["requiredParamIdsToPaths"]
|
117
|
+
|
118
|
+
output = export_section_to_dict(
|
119
|
+
config["codeInfo"],
|
120
|
+
codeInfoChildren,
|
121
|
+
sectionVariant,
|
122
|
+
{"pinned": pinned, "unpinned": unpinned},
|
123
|
+
)
|
124
|
+
yamlValue = section_dict_to_yaml(output, config["codeInfo"], sectionVariant)
|
125
|
+
base = maybe_with_variant_in_filename(config, section_id, variant_id, with_variants)
|
126
|
+
|
127
|
+
with open(folder / f"{base}.yaml", "w") as file:
|
128
|
+
file.write(yamlValue)
|
129
|
+
|
130
|
+
|
131
|
+
def export_list_section(folder, config, section_id, variant_id, with_variants):
|
132
|
+
subfolder_name = maybe_with_variant_in_filename(
|
133
|
+
config, section_id, variant_id, with_variants
|
134
|
+
)
|
135
|
+
children_folder = folder / subfolder_name
|
136
|
+
os.makedirs(children_folder, exist_ok=True)
|
137
|
+
for c in config["sectionVariants"][variant_id]["children"]:
|
138
|
+
export_section(children_folder, config, c, with_variants)
|
139
|
+
|
140
|
+
|
141
|
+
def export_info_section(folder, config, section_id, variant_id, with_variants):
|
142
|
+
base = maybe_with_variant_in_filename(config, section_id, variant_id, with_variants)
|
143
|
+
section = config["sections"][section_id]
|
144
|
+
description = get_section_variant_attr(config, variant_id, "description")
|
145
|
+
renderMarkdown = section["renderMarkdown"]
|
146
|
+
extension = ".md" if renderMarkdown else ".txt"
|
147
|
+
with open(folder / f"{base}{extension}", "w") as file:
|
148
|
+
file.write(description)
|
149
|
+
|
150
|
+
|
151
|
+
def export_param_sweep_section(folder, config, section_id, variant_id, with_variants):
|
152
|
+
for_section_id = get_for_section_id(config, section_id)
|
153
|
+
if not for_section_id:
|
154
|
+
return
|
155
|
+
|
156
|
+
sectionVariant = get_selected_section_variant(config, for_section_id)
|
157
|
+
codeInfoChildren = config["codeInfoCols"][sectionVariant["codeInfoColId"]][
|
158
|
+
"children"
|
159
|
+
]
|
160
|
+
sweep = config["sectionVariants"][variant_id]["sweep"]
|
161
|
+
e = export_param_sweep_section_to_dict(sweep, config["codeInfo"], codeInfoChildren)
|
162
|
+
yamlValue = param_sweep_dict_to_yaml(e)
|
163
|
+
base = maybe_with_variant_in_filename(config, section_id, variant_id, with_variants)
|
164
|
+
with open(folder / f"{base}.yaml", "w") as file:
|
165
|
+
file.write(yamlValue)
|
166
|
+
|
167
|
+
|
168
|
+
def export_global_param_sweep_section(folder, config, section_id, *_, **__):
|
169
|
+
subfolder_name = get_section_name(config, section_id)
|
170
|
+
folder = folder / subfolder_name
|
171
|
+
os.makedirs(folder, exist_ok=True)
|
172
|
+
variantIds = config["sections"][section_id]["variantIds"]
|
173
|
+
for v in variantIds:
|
174
|
+
variant = config["sectionVariants"][v]
|
175
|
+
run_group = variant["runGroup"]
|
176
|
+
e = export_single_run_group_to_dict(
|
177
|
+
run_group,
|
178
|
+
config["sections"],
|
179
|
+
config["sectionVariants"],
|
180
|
+
)
|
181
|
+
yamlValue = run_group_dict_to_yaml(e)
|
182
|
+
base = variant["name"]
|
183
|
+
with open(folder / f"{base}.yaml", "w") as file:
|
184
|
+
file.write(yamlValue)
|
185
|
+
|
186
|
+
|
187
|
+
def export_social_section(folder, config, section_id, *_, **__):
|
188
|
+
section = config["sections"][section_id]
|
189
|
+
url = section["social"]
|
190
|
+
base = get_section_name(config, section_id)
|
191
|
+
with open(folder / f"{base}.txt", "w") as file:
|
192
|
+
file.write(url)
|
193
|
+
|
194
|
+
|
195
|
+
def export_image_section(folder, config, section_id, *_, **__):
|
196
|
+
section = config["sections"][section_id]
|
197
|
+
artifact_group_id = section["artifactGroupIds"][0]
|
198
|
+
artifactId = config["artifactGroups"][artifact_group_id]["artifactTransforms"][0][
|
199
|
+
"artifactId"
|
200
|
+
]
|
201
|
+
artifact = config["artifacts"][artifactId]
|
202
|
+
base = get_section_name(config, section_id)
|
203
|
+
save_base64_to_png(artifact["value"], folder / f"{base}.png")
|
204
|
+
|
205
|
+
|
206
|
+
def export_canvas_rendered_value(folder, config, section_id, *_, **__):
|
207
|
+
section = config["sections"][section_id]
|
208
|
+
if section["renderedValue"]:
|
209
|
+
base = get_section_name(config, section_id)
|
210
|
+
save_base64_to_png(section["renderedValue"], folder / f"{base}.png")
|
211
|
+
|
212
|
+
|
213
|
+
def maybe_with_variant_in_filename(config, section_id, variant_id, with_variants):
|
214
|
+
section_name = get_section_name(config, section_id)
|
215
|
+
variant_name = get_variant_name(config, variant_id)
|
216
|
+
if with_variants:
|
217
|
+
return f"{section_name}@{variant_name}"
|
218
|
+
return section_name
|
219
|
+
|
220
|
+
|
221
|
+
def get_exporter_fn(config, section_id):
|
222
|
+
stype = get_section_type(config, section_id)
|
223
|
+
if stype == C.CODE:
|
224
|
+
return export_code
|
225
|
+
elif stype in [C.SECTION, C.GLOBAL_VARIABLES]:
|
226
|
+
return export_regular_section
|
227
|
+
elif stype in [C.LIST_ROOT, C.DICT_ROOT, C.GROUP]:
|
228
|
+
return export_list_section
|
229
|
+
elif stype == C.INFO:
|
230
|
+
return export_info_section
|
231
|
+
elif stype == C.PARAM_SWEEP:
|
232
|
+
return export_param_sweep_section
|
233
|
+
elif stype == C.GLOBAL_PARAM_SWEEP:
|
234
|
+
return export_global_param_sweep_section
|
235
|
+
elif stype == C.DRAW:
|
236
|
+
return export_canvas_rendered_value
|
237
|
+
elif stype == C.IMAGE:
|
238
|
+
return export_image_section
|
239
|
+
elif stype == C.SOCIAL:
|
240
|
+
return export_social_section
|
241
|
+
elif stype == C.CHART:
|
242
|
+
return export_canvas_rendered_value
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import os
|
2
|
+
from collections import defaultdict
|
3
|
+
from pathlib import Path
|
4
|
+
|
5
|
+
import yaml
|
6
|
+
from yaml.representer import Representer
|
7
|
+
|
8
|
+
from setta.database.db.projects.load import load_full_project
|
9
|
+
|
10
|
+
|
11
|
+
def get_configs_and_root_folder(db, filename):
|
12
|
+
# export defaultdict the same way as dict
|
13
|
+
yaml.add_representer(defaultdict, Representer.represent_dict)
|
14
|
+
configs = load_full_project(db)
|
15
|
+
root_folder = Path(os.getcwd()) / f"{filename}_export"
|
16
|
+
return configs, root_folder
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import sqlite3
|
2
|
+
|
3
|
+
import yaml
|
4
|
+
|
5
|
+
|
6
|
+
def import_database(yaml_filepath, new_database_path):
|
7
|
+
with open(yaml_filepath, "r") as file:
|
8
|
+
database_content = yaml.safe_load(file)
|
9
|
+
|
10
|
+
conn = sqlite3.connect(new_database_path)
|
11
|
+
cursor = conn.cursor()
|
12
|
+
|
13
|
+
for table_name, table_info in database_content["schema"].items():
|
14
|
+
sql = table_info["sql"]
|
15
|
+
cursor.execute(sql)
|
16
|
+
|
17
|
+
for table_name, rows in database_content["data"].items():
|
18
|
+
if not rows:
|
19
|
+
continue
|
20
|
+
# Quote column names to handle reserved keywords
|
21
|
+
columns = ['"' + column + '"' for column in rows[0].keys()]
|
22
|
+
placeholders = ", ".join(["?"] * len(columns))
|
23
|
+
sql = f"INSERT INTO {table_name} ({', '.join(columns)}) VALUES ({placeholders})"
|
24
|
+
for row in rows:
|
25
|
+
cursor.execute(sql, list(row.values()))
|
26
|
+
|
27
|
+
conn.commit()
|
28
|
+
conn.close()
|