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
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:
@@ -0,0 +1,24 @@
|
||||
# SQLPage multiple choice question example
|
||||
|
||||
This is a very simple example of a website that stores a list of
|
||||
possible answers to a multiple choice question in a database table,
|
||||
and then displays the question and the possible answers to the user.
|
||||
|
||||
When the user selects an answer, the website will save the user's
|
||||
choice in the database and display other users' choices as well.
|
||||
|
||||
## Screenshots
|
||||
|
||||
| Question answering form | Results table | Question edition |
|
||||
| --- | --- | --- |
|
||||
|  |  |  |
|
||||
|
||||
## How to run
|
||||
|
||||
Just run the sqlpage binary (`./sqlpage.bin`) from this folder.
|
||||
|
||||
## Interesting files
|
||||
|
||||
[admin.sql](admin.sql) uses the [dynamic component](https://sql-page.com/documentation.sql?component=dynamic#component) to create a single page with one form per MCQ option.
|
||||
|
||||
[website_header.json](website_header.json) contains the [shell](https://sql-page.com/documentation.sql?component=shell#component) that is then used in all pages using the `dynamic` component to create a consistent look and feel between pages.
|
||||
@@ -0,0 +1,36 @@
|
||||
select 'dynamic' as component, sqlpage.read_file_as_text('website_header.json') as properties;
|
||||
|
||||
select 'alert' as component, 'Saved' as title, 'success' as color where $saved is not null;
|
||||
select 'alert' as component, 'Deleted' as title, 'danger' as color where $deleted is not null;
|
||||
select 'alert' as component, 'This option cannot be deleted' as title, 'danger' as color, 'If an option has already been chosen by at least one respondant, then it cannot be deleted' as description where $cannot_delete is not null;
|
||||
|
||||
select 'dynamic' as component,
|
||||
json_array(
|
||||
json_object(
|
||||
'component', 'form',
|
||||
'title', CONCAT('Option ', id),
|
||||
'action', CONCAT('edit_option.sql?id=', id),
|
||||
'validate', '',
|
||||
'id', CONCAT('option', id)
|
||||
),
|
||||
json_object(
|
||||
'type', 'text',
|
||||
'name', 'profile_description',
|
||||
'label', 'Profile description',
|
||||
'value', profile_description
|
||||
),
|
||||
json_object(
|
||||
'type', 'number',
|
||||
'name', 'score',
|
||||
'min', 0,
|
||||
'label', 'Score',
|
||||
'value', score
|
||||
),
|
||||
json_object('component', 'button', 'size', 'sm'),
|
||||
json_object('title', 'Delete', 'outline', 'danger', 'icon', 'trash', 'link', CONCAT('delete_option.sql?id=', id)),
|
||||
json_object('title', 'Save', 'outline', 'success', 'icon', 'device-floppy', 'form', CONCAT('option', id))
|
||||
) as properties
|
||||
from dog_lover_profiles;
|
||||
|
||||
select 'button' as component, 'center' as justify;
|
||||
select 'Create new question' as title, 'create_question.sql' as link;
|
||||
@@ -0,0 +1,4 @@
|
||||
insert into dog_lover_profiles(profile_description, score) values ('', 50)
|
||||
returning
|
||||
'redirect' as component,
|
||||
'admin.sql' as link;
|
||||
@@ -0,0 +1,7 @@
|
||||
select 'redirect' as component, 'admin.sql?cannot_delete' as link
|
||||
where exists (select 1 from answers where profile_id = $id);
|
||||
|
||||
delete from dog_lover_profiles where id = $id
|
||||
returning
|
||||
'redirect' as component,
|
||||
'admin.sql?deleted' as link;
|
||||
@@ -0,0 +1,8 @@
|
||||
services:
|
||||
web:
|
||||
image: lovasoa/sqlpage:main
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- .:/var/www
|
||||
- ./sqlpage:/etc/sqlpage
|
||||
@@ -0,0 +1,6 @@
|
||||
update dog_lover_profiles
|
||||
set profile_description = :profile_description, score = :score
|
||||
where id = $id
|
||||
returning
|
||||
'redirect' as component,
|
||||
'admin.sql?saved' as link;
|
||||
@@ -0,0 +1,9 @@
|
||||
select 'dynamic' as component, sqlpage.read_file_as_text('website_header.json') as properties;
|
||||
|
||||
SELECT
|
||||
'form' AS component,
|
||||
'What dog lover are you ?' AS title,
|
||||
'process.sql' AS action;
|
||||
|
||||
select 'radio' as type, 'profile' as name, id as value, profile_description as label
|
||||
from dog_lover_profiles;
|
||||
@@ -0,0 +1,4 @@
|
||||
insert into answers(profile_id)
|
||||
select CAST(:profile as integer)
|
||||
where :profile is not null
|
||||
returning 'redirect' as component, 'results.sql' as link;
|
||||
@@ -0,0 +1,7 @@
|
||||
select 'dynamic' as component, sqlpage.read_file_as_text('website_header.json') as properties;
|
||||
|
||||
select timestamp, profile_description, score from answers
|
||||
inner join dog_lover_profiles on dog_lover_profiles.id = answers.profile_id;
|
||||
|
||||
select 'csv' as component;
|
||||
select * from answers;
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
@@ -0,0 +1,14 @@
|
||||
create table dog_lover_profiles(
|
||||
id integer primary key,
|
||||
profile_description text not null,
|
||||
score integer not null
|
||||
);
|
||||
|
||||
insert into dog_lover_profiles(profile_description, score)
|
||||
values ('I love dogs', 100), ('I hate them', 0);
|
||||
|
||||
create table answers(
|
||||
id integer primary key,
|
||||
profile_id integer not null references dog_lover_profiles(id),
|
||||
timestamp timestamp not null default current_timestamp
|
||||
);
|
||||
@@ -0,0 +1,24 @@
|
||||
GET http://localhost:8080
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Content-Type" contains "text/html"
|
||||
body contains "What dog lover are you ?"
|
||||
body contains "process.sql"
|
||||
body contains "I love dogs"
|
||||
body contains "I hate them"
|
||||
body not contains "An error occurred"
|
||||
|
||||
POST http://localhost:8080/process.sql
|
||||
[FormParams]
|
||||
profile: 1
|
||||
HTTP 302
|
||||
[Asserts]
|
||||
header "Location" == "results.sql"
|
||||
|
||||
GET http://localhost:8080/results.sql
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Content-Type" contains "text/html"
|
||||
body contains "I love dogs"
|
||||
body contains "100"
|
||||
body not contains "An error occurred"
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"component": "shell",
|
||||
"title": "SQLPage Questions",
|
||||
"icon": "help-hexagon",
|
||||
"link": "/index.sql",
|
||||
"menu_item": ["index", "results", "admin"]
|
||||
}
|
||||
Reference in New Issue
Block a user