FossilRepo

fossilrepo / templates / fossil / explorer_query.html
1
{% extends "base.html" %}
2
{% block title %}Query Runner — {{ project.name }} — Fossilrepo{% endblock %}
3
4
{% block content %}
5
<h1 class="text-2xl font-bold text-gray-100 mb-2">{{ project.name }}</h1>
6
{% include "fossil/_project_nav.html" %}
7
8
<div class="mb-4">
9
<a href="{% url 'fossil:explorer' slug=project.slug %}" class="text-sm text-brand-light hover:text-brand">&larr; Back to Explorer</a>
10
</div>
11
12
<div class="flex items-center justify-between mb-4">
13
<div>
14
<h2 class="text-xl font-bold text-gray-100">SQL Query Runner</h2>
15
<p class="text-sm text-gray-500 mt-1">
16
Execute read-only SELECT queries against the Fossil SQLite database. Results capped at 500 rows.
17
</p>
18
</div>
19
</div>
20
21
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
22
<!-- Query input + results (3/4 width) -->
23
<div class="lg:col-span-3">
24
<form method="get" action="{% url 'fossil:explorer_query' slug=project.slug %}">
25
<div class="rounded-lg bg-gray-800 border border-gray-700 overflow-hidden mb-4">
26
<div class="px-4 py-2 border-b border-gray-700">
27
<label for="sql-input" class="text-xs font-medium text-gray-400 uppercase">SQL Query</label>
28
</div>
29
<textarea
30
id="sql-input"
31
name="sql"
32
rows="5"
33
class="w-full bg-gray-900 text-gray-100 font-mono text-sm p-4 border-0 focus:ring-0 resize-y"
34
placeholder="SELECT * FROM blob LIMIT 10"
35
spellcheck="false">{{ sql }}</textarea>
36
<div class="px-4 py-2 border-t border-gray-700 flex items-center justify-between">
37
<span class="text-xs text-gray-600">Only SELECT queries are allowed. No INSERT, UPDATE, DELETE, DROP, etc.</span>
38
<button type="submit" class="inline-flex items-center px-4 py-1.5 text-sm font-medium rounded-md bg-brand text-white hover:bg-brand-hover">
39
Run
40
</button>
41
</div>
42
</div>
43
</form>
44
45
{% if error %}
46
<div class="rounded-lg bg-red-900/30 border border-red-700 p-4 mb-4">
47
<p class="text-sm text-red-300 font-mono">{{ error }}</p>
48
</div>
49
{% endif %}
50
51
{% if columns %}
52
<div class="rounded-lg bg-gray-800 border border-gray-700 overflow-x-auto">
53
<table class="min-w-full divide-y divide-gray-700">
54
<thead>
55
<tr>
56
{% for col in columns %}
57
<th class="px-4 py-3 text-left text-xs font-medium text-gray-400 uppercase tracking-wider whitespace-nowrap">{{ col }}</th>
58
{% endfor %}
59
</tr>
60
</thead>
61
<tbody class="divide-y divide-gray-700 font-mono text-xs">
62
{% for row in results %}
63
<tr class="hover:bg-gray-700/50">
64
{% for cell in row %}
65
<td class="px-4 py-2 text-gray-300 whitespace-nowrap max-w-xs truncate">{{ cell|default:"NULL" }}</td>
66
{% endfor %}
67
</tr>
68
{% endfor %}
69
</tbody>
70
</table>
71
</div>
72
<div class="mt-2 text-xs text-gray-500">
73
{{ results|length }} row{{ results|length|pluralize }} returned{% if results|length >= 500 %} (limited to 500){% endif %}
74
</div>
75
{% elif sql and not error %}
76
<div class="rounded-lg bg-gray-800 border border-gray-700 p-8 text-center">
77
<p class="text-sm text-gray-500">No results.</p>
78
</div>
79
{% endif %}
80
</div>
81
82
<!-- Table list sidebar (1/4 width) -->
83
<div class="lg:col-span-1">
84
<div class="rounded-lg bg-gray-800 border border-gray-700 p-3 sticky top-6">
85
<h3 class="text-xs font-medium text-gray-400 uppercase mb-2">Available Tables</h3>
86
{% if table_names %}
87
<div class="space-y-0.5 max-h-96 overflow-y-auto">
88
{% for name in table_names %}
89
<button
90
type="button"
91
onclick="document.getElementById('sql-input').value = 'SELECT * FROM {{ name }} LIMIT 25'; document.getElementById('sql-input').focus();"
92
class="block w-full text-left px-2 py-1 text-xs font-mono text-gray-400 hover:text-gray-200 hover:bg-gray-700 rounded">
93
{{ name }}
94
</button>
95
{% endfor %}
96
</div>
97
{% else %}
98
<p class="text-xs text-gray-600">Run a query to see tables, or go to the <a href="{% url 'fossil:explorer' slug=project.slug %}" class="text-brand-light hover:text-brand">Explorer</a>.</p>
99
{% endif %}
100
</div>
101
</div>
102
</div>
103
{% endblock %}
104

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button