5. Logic & Database#
Before integrating with our full app, let’s build a standalone version to understand the core patterns.
Create the database table#
Bialet uses SQLite. When you run the server, a _db.sqlite3 file is created
automatically. Connect to it with SQLite
Browser or the SQLite
CLI and run:
CREATE TABLE simple_poll (answer TEXT PRIMARY KEY, votes INT);
INSERT INTO simple_poll VALUES ("Yes", 0);
INSERT INTO simple_poll VALUES ("No", 0);
Query and display#
Create simple_poll.wren:
var options = `SELECT * FROM simple_poll`.fetch()
Response.out(
<html>
<body>
<h1>Has web development become overly complex?</h1>
<form method="post">
{{ options.map {|opt| <p>
<label>
<input type="radio" name="vote" value="{{ opt["answer"] }}">
{{ opt["answer"] }}
</label>
</p> } }}
<p><input type="submit" value="Vote"></p>
</form>
</body>
</html>
)
The backtick string `SELECT * FROM simple_poll` is a Query object
— a prepared statement. .fetch() executes it and returns all rows as a
list of maps.
Handle POST#
Add vote handling above the query:
if (Request.isPost) {
var vote = Request.post("vote")
`UPDATE simple_poll SET votes = votes + 1 WHERE answer = ?`.query(vote)
System.log("Voted for %(vote)")
}
var options = `SELECT * FROM simple_poll`.fetch()
Request.isPostchecks if the form was submittedRequest.post("vote")reads the form field.query(vote)executes a parameterized UPDATE?placeholders prevent SQL injection — never concatenate user input
System.log() prints to the server terminal — useful for debugging.
Show results after voting#
Use a ternary to switch between the form and the results view:
var vote
if (Request.isPost) {
vote = Request.post("vote")
`UPDATE simple_poll SET votes = votes + 1 WHERE answer = ?`.query(vote)
}
var options = `SELECT * FROM simple_poll`.fetch()
return <html>
<body>
<h1>Has web development become overly complex?</h1>
{{ !vote ?
<form method="post">
{{ options.map {|opt| <p>
<label>
<input type="radio" name="vote" value="{{ opt["answer"] }}">
{{ opt["answer"] }}
</label>
</p> } }}
<p><input type="submit" value="Vote"></p>
</form>
:
<main>
<p>Thank you for voting!</p>
<ul>
{{ options.map {|opt|
<li>{{ opt["answer"] }} - {{ opt["votes"] }} votes</li>
} }}
</ul>
<p><a href="">Vote again</a></p>
</main>
}}
</body>
</html>
The pattern {{ condition ? <true-branch> : <false-branch> }} is a ternary
— the Wren equivalent of if/else inline.
For a deeper dive into queries, see Database.
Previous: 4. Templates | Next: 6. Migrations