chore: import upstream snapshot with attribution
CI / compile_and_lint (push) Failing after 0s
CI / docker_build (linux/amd64, -linux-amd64-duckdb, duckdb) (push) Failing after 0s
CI / docker_build (linux/arm64, -linux-arm64, minimal) (push) Failing after 2s
CI / docker_build (linux/arm64, -linux-arm64-duckdb, duckdb) (push) Failing after 1s
CI / docker_build (linux/amd64, minimal) (push) Failing after 1s
CI / test (, sqlite, sqlite::memory:) (push) Has been skipped
CI / test (mssql, mssql, mssql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (mysql, mysql, mysql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (oracle, oracle, Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!) (push) Has been skipped
CI / test (postgres, odbc, Driver=PostgreSQL Unicode;Server=127.0.0.1;Port=5432;Database=sqlpage;UID=root;PWD=Password123!, true) (push) Has been skipped
CI / test (postgres, postgres, postgres://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / playwright (push) Has been skipped
CI / docker_build (linux/arm/v7, -linux-arm-v7, minimal) (push) Failing after 0s
CI / hurl_examples (push) Failing after 8s
deploy website / deploy_official_site (push) Failing after 1s
CI / hurl (${{ matrix.example }}) (push) Has been skipped
CI / docker_push (duckdb) (push) Has been cancelled
CI / docker_push (minimal) (push) Has been cancelled
CI / windows_test (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:31:57 +08:00
commit d718c5a372
986 changed files with 74597 additions and 0 deletions
@@ -0,0 +1,5 @@
FROM lovasoa/sqlpage:latest
COPY sqlpage /etc/sqlpage
COPY src /var/www
ENV DATABASE_URL=sqlite:///tmp/pokemon.db?mode=rwc
@@ -0,0 +1,27 @@
# Roundest (SQLPage Version)
This is a simple web app that allows you to vote on which Pokemon is the most round.
| Vote UI | Results UI |
| --- | --- |
| ![vote ui screenshot](screenshots/vote.png) | ![results ui](screenshots/results.png) |
It demonstrates how to build an entirely custom web app,
without using any of the pre-built components of SQLPage.
All the custom components are in the [`sqlpage/templates/`](./sqlpage/templates/) folder.
## Running the app
### Using an installed version of SQLPage
```
sqlpage --web-root src
```
### Using Docker
```
docker build -t roundest-sqlpage .
docker run -p 8080:8080 -it roundest-sqlpage
```
@@ -0,0 +1,5 @@
services:
web:
build: .
ports:
- "8080:8080"
Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

@@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS pokemon (
dex_id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
up_votes INTEGER DEFAULT 0,
down_votes INTEGER DEFAULT 0
);
@@ -0,0 +1,30 @@
<div
class="container d-flex justify-content-center align-items-center min-vh-75 gap-5"
>
<form action="/vote.sql" method="POST" class="d-flex gap-5">
{{#each_row}}
<div class="text-center">
<input type="hidden" name="option_{{@row_index}}" value="{{dexNumber}}" />
<img
src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/{{dexNumber}}.png"
class="img-fluid"
style="width: 256px; height: 256px; image-rendering: pixelated;"
alt="{{name}}"
/>
<div class="mt-3">
<span class="text-secondary fs-5">#{{dexNumber}}</span>
<h2 class="fs-1 fw-bold text-capitalize">{{name}}</h2>
<div class="mt-4">
<button
type="submit"
formaction="/vote.sql?voted={{dexNumber}}"
class="btn btn-primary btn-lg px-4"
>
Vote
</button>
</div>
</div>
</div>
{{/each_row}}
</form>
</div>
@@ -0,0 +1,29 @@
<div class="container py-4">
<div class="row g-4">
{{#each_row}}
<div class="col-12">
<div class="d-flex align-items-center gap-4 p-4 bg-dark bg-opacity-40 rounded shadow">
<div class="fs-3 fw-bold text-secondary" style="width: 2rem">
#{{rank}}
</div>
<img src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/{{dex_id}}.png" alt="{{name}}" class="img-fluid" style="width: 5rem; height: 5rem" />
<div class="flex-grow-1">
<div class="text-secondary small">#{{dex_id}}</div>
<h2 class="fs-4 fw-semibold text-capitalize text-white">{{name}}</h2>
</div>
<div class="text-end">
<div class="fs-3 fw-bold text-info">
{{win_percentage}}%
</div>
<div class="small text-secondary">
{{up_votes}}W - {{down_votes}}L
</div>
</div>
</div>
</div>
{{/each_row}}
</div>
</div>
@@ -0,0 +1,39 @@
<html lang="en">
<head>
<link rel="stylesheet" href="{{static_path 'sqlpage.css'}}">
</head>
<body class="d-flex flex-column min-vh-100 bg-dark text-white border-top border-info">
<header class="py-3 px-4">
<div class="d-flex align-items-center justify-content-between">
<div class="d-flex align-items-baseline">
<a href="/" class="text-decoration-none text-white">
<h1 class="fw-bold fs-2 mb-0">
round<span class="text-info">est</span>
<span class="text-secondary fw-light ms-2 fs-3">
(SQLPage Version)
</span>
</h1>
</a>
</div>
<nav class="d-flex gap-4">
<a href="/results.sql" class="text-white text-decoration-none fs-5 hover-underline">
Results
</a>
</nav>
</div>
</header>
<main class="flex-grow-1">{{~#each_row~}}{{~/each_row~}}</main>
<footer class="text-center py-2 text-secondary fw-light">
<a
href="https://github.com/t3dotgg/1app5stacks"
target="_blank"
rel="noopener noreferrer"
class="text-secondary"
>
GitHub
</a>
</footer>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

@@ -0,0 +1,8 @@
select 'redirect' as component, '/populate.sql' as link
where not exists(select 1 from pokemon);
select 'pokemon' as component;
select dex_id as dexNumber, name
from pokemon
order by random() limit 2;
@@ -0,0 +1,12 @@
-- This updates our pokemon table with fresh data from pokeapi.co
insert into pokemon (dex_id, name)
select
cast(rtrim(substr(value->>'url',
length('https://pokeapi.co/api/v2/pokemon/') + 1),
'/') as integer) as dex_id,
value->>'name' as name
from json_each(
sqlpage.fetch('https://pokeapi.co/api/v2/pokemon?limit=100000&offset=0') -> 'results'
);
select 'redirect' as component, '/' as link;
@@ -0,0 +1,15 @@
select 'results' as component;
with ranked as (
select
*,
case
when (up_votes + down_votes) = 0 then 0
else 100 * up_votes / (up_votes + down_votes)
end as win_percentage,
up_votes - down_votes as score
from pokemon
)
select *, rank() over (order by score desc) as rank
from ranked
order by win_percentage desc, score desc;
@@ -0,0 +1,7 @@
update pokemon
set
up_votes = up_votes + (dex_id = $voted),
down_votes = down_votes + (dex_id != $voted)
where dex_id IN (:option_0, :option_1);
select 'redirect' as component, '/' as link;
@@ -0,0 +1,7 @@
GET http://localhost:8080/
HTTP 302
[Asserts]
header "Location" == "/populate.sql"
GET http://localhost:8080/favicon.ico
HTTP 200