Skip to content

Commit 3298a83

Browse files
authored
Merge pull request #494 from lovasoa/sqlpage.link
new sqlpage.link function
2 parents 9c47ec9 + 47e419b commit 3298a83

File tree

22 files changed

+341
-55
lines changed

22 files changed

+341
-55
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@
2727
- Updated apexcharts.js to [v3.50.0](https://github.com/apexcharts/apexcharts.js/releases/tag/v3.50.0)
2828
- Improve truncation of long page titles
2929
- ![screenshot long title](https://github.com/lovasoa/SQLpage/assets/552629/9859023e-c706-47b3-aa9e-1c613046fdfa)
30+
- new function: [`sqlpage.link`](https://sql.ophir.dev/functions.sql?function=link#function) to easily create links with parameters between pages. For instance, you can now use
31+
```sql
32+
select 'list' as component;
33+
select
34+
product_name as title,
35+
sqlpage.link('product.sql', json_object('product', product_name)) as link
36+
from products;
37+
```
38+
- Before, you would usually build the link manually with `CONCAT('/product.sql?product=', product_name)`, which would fail if the product name contained special characters like '&'. The new `sqlpage.link` function takes care of encoding the parameters correctly.
39+
- Calls to `json_object` are now accepted as arguments to SQLPage functions. This allows you to pass complex data structures to functions such as `sqlpage.fetch`, `sqlpage.run_sql`, and `sqlpage.link`.
3040

3141
## 0.24.0 (2024-06-23)
3242
- in the form component, searchable `select` fields now support more than 50 options. They used to display only the first 50 options.

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM --platform=$BUILDPLATFORM rust:1.78-slim as builder
1+
FROM --platform=$BUILDPLATFORM rust:1.79-slim as builder
22
WORKDIR /usr/src/sqlpage
33
ARG TARGETARCH
44
ARG BUILDARCH

examples/CRUD - Authentication/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ SET $_username = (
2121
```sql
2222
SELECT
2323
'redirect' AS component,
24-
'/login.sql?path=' || $_curpath AS link
24+
sqlpage.link('/login.sql', json_object('path', $_curpath)) AS link
2525
WHERE $_username IS NULL AND $_session_required;
2626
```
2727
4. The login page renders the login form, accepts the user credentials, and redirects to create_session.sql, passing the login credentials as POST variables.

examples/CRUD - Authentication/www/create_session.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
SELECT
44
'authentication' AS component,
5-
'login.sql?' || ifnull('path=' || $path, '') || '&error=1' AS link,
5+
'login.sql?' || ifnull('path=' || sqlpage.url_encode($path), '') || '&error=1' AS link,
66
:password AS password,
77
(SELECT password_hash
88
FROM accounts

examples/charts, computations and custom components/index.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ SELECT 'hero' as component,
1111
'Tap Tempo' as title,
1212
'Tap Tempo is a tool to **measure a tempo in bpm** by clicking a button in rythm.' as description_md,
1313
'drums by Nana Yaw Otoo.jpg' as image,
14-
'taptempo.sql?session=' || random() as link,
14+
sqlpage.link('taptempo.sql', json_object('session', random())) as link,
1515
'Start tapping !' as link_text;
1616

1717
SELECT 'text' as component,

examples/charts, computations and custom components/taptempo.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ SELECT 'big_button' as component,
88
(SELECT bpm || ' bpm' FROM tap_bpm WHERE tapping_session = $session ORDER BY day DESC LIMIT 1),
99
'Tap'
1010
) AS text,
11-
'taptempo.sql?session=' || $session as link;
11+
sqlpage.link('taptempo.sql', json_object('session', $session)) as link;
1212

1313
SELECT 'chart' as component, 'BPM over time' as title, 'area' as type, 'indigo' as color, 0 AS ymin, 200 AS ymax, 'BPM' as ytitle;
1414
SELECT * FROM (
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
INSERT INTO games(id)
22
VALUES(random())
33
RETURNING
4-
'http_header' as component,
5-
'game.sql?id='||id as "Location";
6-
7-
SELECT 'text' as component, 'redirecting to game...' as contents;
4+
'redirect' as component,
5+
CONCAT('game.sql?id=', id) as link;

examples/corporate-conundrum/game.sql

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@ INSERT INTO players(name, game_id)
55
SELECT $Player as name,
66
$id::integer as game_id
77
WHERE $Player IS NOT NULL;
8+
89
SELECT 'list' as component,
910
'Players' as title;
1011
SELECT name as title,
11-
'next-question.sql?game_id=' || game_id || '&player=' || name as link
12+
sqlpage.link(
13+
'next-question.sql',
14+
json_object(
15+
'game_id', game_id,
16+
'player', name
17+
)
18+
) as link
1219
FROM players
1320
WHERE game_id = $id::integer;
1421
---------------------------
Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
1-
SELECT 'http_header' as component,
2-
COALESCE(
3-
(
4-
SELECT 'question.sql?game_id=' || $game_id || '&question_id=' || game_questions.question_id || '&player=' || $player as "Location"
5-
FROM game_questions
6-
WHERE game_id = $game_id::integer
7-
AND NOT EXISTS (
8-
-- This will filter out questions that have already been answered by the player
9-
SELECT 1
10-
FROM answers
11-
WHERE answers.game_id = game_questions.game_id
12-
AND answers.player_name = $player
13-
AND answers.question_id = game_questions.question_id
14-
)
15-
ORDER BY game_order
16-
LIMIT 1
17-
),
18-
'game-over.sql?game_id=' || $game_id
19-
) as 'Location';
20-
SELECT 'text' as component,
21-
'redirecting to next question...' as contents;
1+
-- We need to redirect the user to the next question in the game if there is one, or to the game over page if there are no more questions.
2+
with next_question as (
3+
SELECT
4+
'question.sql' as page,
5+
json_object(
6+
'game_id', $game_id,
7+
'question_id', game_questions.question_id,
8+
'player', $player
9+
) as params
10+
FROM game_questions
11+
WHERE game_id = $game_id::integer
12+
AND NOT EXISTS (
13+
-- This will filter out questions that have already been answered by the player
14+
SELECT 1
15+
FROM answers
16+
WHERE answers.game_id = game_questions.game_id
17+
AND answers.player_name = $player
18+
AND answers.question_id = game_questions.question_id
19+
)
20+
ORDER BY game_order
21+
LIMIT 1
22+
),
23+
next_page as (
24+
SELECT * FROM next_question
25+
UNION ALL
26+
SELECT 'game-over.sql' as page, json_object('game_id', $game_id) as params
27+
WHERE NOT EXISTS (SELECT 1 FROM next_question)
28+
)
29+
SELECT 'redirect' as component,
30+
sqlpage.link(page, params) as link
31+
FROM next_page
32+
LIMIT 1;

examples/corporate-conundrum/question.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ select * FROM sqlpage_shell;
33
SELECT 'form' as component,
44
question_text as title,
55
'Submit your answer' as validate,
6-
'wait.sql?game_id='|| $game_id ||'&question_id=' || $question_id ||'&player=' || $player as action
6+
sqlpage.link('wait.sql', json_object('game_id', $game_id, 'question_id', $question_id, 'player', $player)) as action
77
FROM questions
88
where id = $question_id::integer;
99

0 commit comments

Comments
 (0)