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,20 @@
|
||||
# Handling json data in MySQL
|
||||
|
||||
This demonstrates both how to produce json data from a SQL query in MySQL
|
||||
and how to consume json data from SQLPage.
|
||||
|
||||

|
||||
|
||||
## Documentation
|
||||
|
||||
This example demonstrates how to consume [JSON](https://en.wikipedia.org/wiki/JSON) data from a MySQL database,
|
||||
using the [`JSON_TABLE`](https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html)
|
||||
function to parse the JSON data into a table.
|
||||
|
||||
The main page contains a form with a select input, in which the user can
|
||||
select one or multiple values.
|
||||
|
||||
The values are then sent to the server, and are accessible from SQL queries in the form of a JSON array.
|
||||
|
||||
The SQL then uses the `JSON_TABLE` function to transform the JSON array into a temporary table,
|
||||
which is then used to process the data and insert it into the database.
|
||||
@@ -0,0 +1,17 @@
|
||||
services:
|
||||
web:
|
||||
image: lovasoa/sqlpage:main # main is cutting edge, use sqlpage/SQLPage:latest for the latest stable version
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- .:/var/www
|
||||
- ./sqlpage:/etc/sqlpage
|
||||
depends_on:
|
||||
- db
|
||||
environment:
|
||||
DATABASE_URL: mysql://root:secret@db/sqlpage
|
||||
db: # The DB environment variable can be set to "mariadb" or "postgres" to test the code with different databases
|
||||
image: mariadb:12 # support for json_table was added in mariadb 10.6
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: secret
|
||||
MYSQL_DATABASE: sqlpage
|
||||
@@ -0,0 +1,35 @@
|
||||
select 'form' as component, 'Create a new Group' as title, 'Create' as validate;
|
||||
select 'Name' as name;
|
||||
|
||||
insert into groups(name) select :Name where :Name is not null;
|
||||
|
||||
select 'list' as component, 'Groups' as title, 'No group yet' as empty_title;
|
||||
select name as title from groups;
|
||||
|
||||
select 'form' as component, 'Add a user' as title, 'Add' as validate;
|
||||
select 'UserName' as name, 'Name' as label;
|
||||
select
|
||||
'Memberships[]' as name,
|
||||
'Group memberships' as label,
|
||||
'select' as type,
|
||||
TRUE as multiple,
|
||||
'press ctrl to select multiple values' as description,
|
||||
json_arrayagg(json_object("label", name, "value", id)) as options
|
||||
from groups;
|
||||
|
||||
insert into users(name) select :UserName where :UserName is not null;
|
||||
insert into group_members(group_id, user_id)
|
||||
select group_name, last_insert_id()
|
||||
from json_table(:Memberships, '$[*]' columns (
|
||||
group_name int path '$'
|
||||
)) as json_elems
|
||||
where :Memberships is not null;
|
||||
|
||||
select 'list' as component, 'Users' as title, 'No user yet' as empty_title;
|
||||
select
|
||||
users.name as title,
|
||||
group_concat(groups.name) as description
|
||||
from users
|
||||
left join group_members on users.id = group_members.user_id
|
||||
left join groups on groups.id = group_members.group_id
|
||||
group by users.id, users.name;
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
@@ -0,0 +1,17 @@
|
||||
create table users (
|
||||
id int primary key auto_increment,
|
||||
name varchar(255) not null
|
||||
);
|
||||
|
||||
create table groups (
|
||||
id int primary key auto_increment,
|
||||
name varchar(255) not null
|
||||
);
|
||||
|
||||
create table group_members (
|
||||
group_id int not null,
|
||||
user_id int not null,
|
||||
primary key (group_id, user_id),
|
||||
foreign key (group_id) references groups (id),
|
||||
foreign key (user_id) references users (id)
|
||||
);
|
||||
@@ -0,0 +1,18 @@
|
||||
CREATE TABLE questions(
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
question_text TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE survey_answers(
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
question_id INT,
|
||||
answer TEXT,
|
||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (question_id) REFERENCES questions(id)
|
||||
);
|
||||
|
||||
|
||||
INSERT INTO questions(question_text) VALUES
|
||||
('What is your name?'),
|
||||
('What is your age?'),
|
||||
('What is your favorite color?');
|
||||
@@ -0,0 +1,27 @@
|
||||
SELECT 'form' as component, 'Survey' as title;
|
||||
SELECT id as name, question_text as label, 'textarea' as type
|
||||
FROM questions;
|
||||
|
||||
-- Save all the answers to the database, whatever the number and id of the questions
|
||||
INSERT INTO survey_answers (question_id, answer)
|
||||
SELECT
|
||||
question_id,
|
||||
json_unquote(
|
||||
json_extract(
|
||||
sqlpage.variables('post'),
|
||||
concat('$."', question_id, '"')
|
||||
)
|
||||
)
|
||||
FROM json_table(
|
||||
json_keys(sqlpage.variables('post')),
|
||||
'$[*]' columns (question_id int path '$')
|
||||
) as question_ids;
|
||||
|
||||
-- Show the answers
|
||||
select 'card' as component, 'Survey results' as title;
|
||||
select
|
||||
questions.question_text as title,
|
||||
survey_answers.answer as description,
|
||||
'On ' || survey_answers.timestamp as footer
|
||||
from survey_answers
|
||||
inner join questions on questions.id = survey_answers.question_id;
|
||||
@@ -0,0 +1,37 @@
|
||||
GET http://localhost:8080
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Content-Type" contains "text/html"
|
||||
xpath "//html" exists
|
||||
xpath "//body" exists
|
||||
body not contains "An error occurred"
|
||||
|
||||
POST http://localhost:8080/
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
[FormParams]
|
||||
Name: Hurl Analysts
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
body contains "Hurl Analysts"
|
||||
body not contains "An error occurred"
|
||||
|
||||
POST http://localhost:8080/
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
[FormParams]
|
||||
Name: Hurl Reviewers
|
||||
HTTP 200
|
||||
[Captures]
|
||||
analysts_id: xpath "string(//select[@name='Memberships[]']/option[normalize-space(.)='Hurl Analysts']/@value)"
|
||||
reviewers_id: xpath "string(//select[@name='Memberships[]']/option[normalize-space(.)='Hurl Reviewers']/@value)"
|
||||
[Asserts]
|
||||
body contains "Hurl Reviewers"
|
||||
body not contains "An error occurred"
|
||||
|
||||
POST http://localhost:8080/
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
`UserName=Hurl+User&Memberships%5B%5D={{analysts_id}}&Memberships%5B%5D={{reviewers_id}}`
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
body contains "Hurl User"
|
||||
body htmlUnescape contains "Hurl Analysts,Hurl Reviewers"
|
||||
body not contains "An error occurred"
|
||||
Reference in New Issue
Block a user