Skip to content

Commit

Permalink
Rough prototype of cross-database-joins, refs #283
Browse files Browse the repository at this point in the history
This is a quick-and-dirty proof of concept.
  • Loading branch information
simonw committed May 24, 2018
1 parent bd30c69 commit 7a3040f
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 5 deletions.
2 changes: 1 addition & 1 deletion datasette/templates/database.html
Expand Up @@ -16,7 +16,7 @@ <h1 style="padding-left: 10px; border-left: 10px solid #{{ database_hash[:6] }}"

{% block description_source_license %}{% include "_description_source_license.html" %}{% endblock %}

<form class="sql" action="/{{ database }}-{{ database_hash }}" method="get">
<form class="sql" action="/{{ database }}{% if database_hash %}-{{ database_hash }}{% endif %}" method="get">
<h3>Custom SQL query</h3>
<p><textarea name="sql">select * from {{ tables[0].name|escape_sqlite }}</textarea></p>
<p><input type="submit" value="Run SQL"></p>
Expand Down
2 changes: 1 addition & 1 deletion datasette/templates/query.html
Expand Up @@ -23,7 +23,7 @@

<h1 style="padding-left: 10px; border-left: 10px solid #{{ database_hash[:6] }}">{{ database }}</h1>

<form class="sql" action="/{{ database }}-{{ database_hash }}{% if canned_query %}/{{ canned_query }}{% endif %}" method="get">
<form class="sql" action="/{{ database }}{% if database_hash %}-{{ database_hash }}{% endif %}{% if canned_query %}/{{ canned_query }}{% endif %}" method="get">
<h3>Custom SQL query{% if rows %} returning {% if truncated %}more than {% endif %}{{ "{:,}".format(rows|length) }} row{% if rows|length == 1 %}{% else %}s{% endif %}{% endif %}</h3>
{% if editable %}
<p><textarea name="sql">{% if query and query.sql %}{{ query.sql }}{% else %}select * from {{ tables[0].name|escape_sqlite }}{% endif %}</textarea></p>
Expand Down
17 changes: 15 additions & 2 deletions datasette/views/base.py
Expand Up @@ -107,6 +107,8 @@ def resolve_db_name(self, db_name, **kwargs):
hash = None
else:
name = db_name
if name == "memory":
return "memory", "", None
# Verify the hash
try:
info = databases[name]
Expand Down Expand Up @@ -143,14 +145,25 @@ async def execute(
def sql_operation_in_thread():
conn = getattr(connections, db_name, None)
if not conn:
info = self.ds.inspect()[db_name]
if db_name == "memory":
filename = ":memory:"
else:
info = self.ds.inspect()[db_name]
filename = info["file"]
conn = sqlite3.connect(
"file:{}?immutable=1".format(info["file"]),
"file:{}?immutable=1".format(filename),
uri=True,
check_same_thread=False,
)
self.ds.prepare_connection(conn)
setattr(connections, db_name, conn)
if db_name == "memory":
# Loop through and attach all the other DBs
for dbname, dbinfo in self.ds.inspect().items():
sql2 = 'ATTACH DATABASE "file:{}?immutable=1" AS [{}];'.format(
dbinfo["file"], dbname
)
conn.execute(sql2)

time_limit_ms = self.ds.sql_time_limit_ms
if custom_time_limit and custom_time_limit < self.ds.sql_time_limit_ms:
Expand Down
12 changes: 11 additions & 1 deletion datasette/views/database.py
Expand Up @@ -15,7 +15,17 @@ async def data(self, request, name, hash):
validate_sql_select(sql)
return await self.custom_sql(request, name, hash, sql)

info = self.ds.inspect()[name]
if name == "memory":
info = {"tables": {
"sqlite_master": {
"name": "sqlite_master",
"hidden": False,
"columns": [],
"count": 0,
}
}, "views": []}
else:
info = self.ds.inspect()[name]
metadata = self.ds.metadata.get("databases", {}).get(name, {})
self.ds.update_with_inherited_metadata(metadata)
tables = list(info["tables"].values())
Expand Down

0 comments on commit 7a3040f

Please sign in to comment.