Server Side JavaScript mit v8cgi - Teil II

> SQLite arangieren
> Filtern, Validieren und Speichern
> Kleiner Exkurs ins Reich des HTML5
Nach der Einführung in der Welt des SJS sind wir bereit für unser erstes Progrämmchen: Ein klassisches Gästebuch, einfach gehalten, bestehend aus einem Script und eine Art Bootstrap-Datei (Application-Progger werden's kennen), einer SQLite-Datei (Datenbanken sind auch nur Dateien) und einem Frontent-File in HTML5 mit dem Layout.
SQLite arangieren
SQLite-Files müssen «von Hand» zusammengestellt werden. Der folgende Code checkt vorerst ob die Datei vorhanden ist und generiert diese bei bedarf.
//set db
include('sqlite');
if (!new File(memory).exists()) {
var db = new SQLite().open(memory);
db.query("create table entries (
id integer primary key,
name varchar(32),
link varchar(128),
text text
)");
db.close();
}
var db = new SQLite().open(memory);
Vielleicht gibt es elegantere Möglichkeiten um das zu bewerkstelligen?
Die Daten werden in einem Array bestehend aus JSONs eingelesen
//get data
var result = db.query('SELECT * FROM entries');
var entries = result.fetchObjects();
und anschließend an das Template weitergereicht
//set contents
response.write(
new Template().process('layout', {
msg: msg,
entries: entries,
input: input
}));
Voila!
Filtern, Validieren und Speichern
Jetzt geht es an die Inputs. Zum Filtern benutzen wir die aufgesetzte HTML.escape Funktion. Name und Text sind Pflichtfelder, diese müssen mit dem letzten Datensatz aus der Datenbank verglichen werden um doppelte Einträge zu vermeiden.
//validate inputs
if (input.name || input.text) {
input.name = HTML.escape(input.name);
input.link = HTML.escape(input.link);
input.text = HTML.escape(input.text);
if (!input.name) msg.warning = 'Fehler: Name fehlt';
else if (!input.text) msg.warning = 'Fehler: Textfeld leer';
else { // auf wiederholungen prüfen
var q = "select name, text from entries order by id desc limit 1";
var lastEntry = db.query(q).fetchObjects()[0];
if (lastEntry && lastEntry.name==input.name && lastEntry.text==input.text)
msg.warning = 'Fehler: Dublette!';
}
}
Nach der Prüfung müssen die Daten in die Datenbank:
//update db
if (input.text && msg.warning=='') {
var q = "insert into entries (name, link, text) "
+ "values ('"+input.name+"', '"+input.link+"', '"+input.text+"')";
if (db.query(q)) {
msg.success = 'Dein Post wurde eingetragen.';
input = {};
}
else msg.warning = 'Beim speichern ist Datenbanken-Fehler aufgetreten.';
}
Leider habe ich die nicht zu SQLite überreden können…
Und hier die (viel zu lange?) vollständige Datei: guestbook.js
//Okt 2009 SJS Tickler Guestbook Script
function guestbook ()
{
var input = request.post;
var memory = 'memory.sql';
var msg = { success:'', warning:'' };
var entries;
var logs;
//set db
//validate inputs
//update db
//get data
//set contents
}
guestbook();
Kleiner Exkurs ins Reich des HTML5
Hier geht es um die Zukunft! Darum will ich euch das HTML5 lehren, so machet mir die Header und die Footer auf.
Über die Jahre haben sich aus dem WebDesign gewisse Standards herausgebildet. Webseiten ähneln im Grunde Listen (section) mit Einträgen (article). Daneben gibt es einen Header, Navigation (nav), Seitenleisten (aside), Benachrichtigungen (dialog) und die Fußzeile (footer).
Aber ein Beispiel sagt ja mehr als Tausend Worte:
Die layout.template
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>SJS Tickler</title>
<!--[if IE]><script src="html5.js"></script><![endif]-->
<style>
section, header, dialog, article {display:block;}
section { width:340px; margin:20px; font:.8em Verdana; }
header { font-weight:bold; }
dialog { padding:4px; }
dialog#success { color:green; }
dialog#fail { color:red; }
article { margin-bottom:1em; border:1px solid #ddd; padding:4px; }
span.entry_name{ font-weight:bold; }
</style>
</head>
<body>
<section id="tickler">
<header>SJS Tickler</header>
<dialog id="success">$(data.msg.success||'')</dialog>
<dialog id="fail">$(data.msg.warning||'')</dialog>
$code(for (var i=0; i < data.entries.length; i++) {
var entry = data.entries[i];
)
<article id="entries">
<span class="entry_id">#$(entry.id)</span>
$code( if (entry.link) { )
<span class="entry_name"><a href="$(entry.link)">$(entry.name)</a>:</span>
$code( } else { )
<span class="entry_name">$(entry.name):</span>
$code( } )
<span class="entry_text">$(entry.text)</span>
</article>
$code( } )
<hr/>
<form id="user_form" method="POST" accept-charset="UTF-8" action="">
<label>Name</label>
<input type="text" name="name" value="$(data.input.name||'')">
<label>Link</label>
<input type="text" name="link" value="$(data.input.link||'')">
<label>Nachricht</label>
<textarea name="text">$(data.input.text||'')</textarea>
<input type="submit">
</form>
</section>
</body>
</html>
Zwei Dinge sind HTML5-Spezifisch: Erstens muss ein kleines eingebunden werden, dass den Internet Explorer die neuen Tags beibringt. Zweitens sind die Tags nicht im block-style dargestellt, was aber nicht weiter tragisch ist.
That's easy, isn't it?
Im nächsten Teil will ich in die objektorientierte Programmierung eingehen und mich an einem RSS-Reader versuchen.











Kommentare (9)
behoben wurde.
wildeuter
unsicherheitsagent
der die programmiersprache selbst besteht ja auch aus Klassen-Bibliotheken. diese werden dann so
exports.HTML = HTML als global deklariert. das macht es es aber wie gesagt nicht möglich frameworks aus dem klassischen javascript zu verweden…
rhino hin oder hier, es muss schon ein mod sein, das auf dem windows-apache läuft und somit für die «breite masse» verfügbar ist, damit es irgendwie erfolg hat und nicht nur, wie bisher, eine nette spielerei für C-programmierer bleibt.
wildeuter
Und dass die Variablen im globalen Namespace nicht verfügbar sind ist mir leicht unwahrscheinlich,
schau dir mal das an: .
unsicherheitsagent
wildeuter
wildeuter
BuzzEins
wildeuter
var error = e.stack? (e.stack).replace(/ at /g,'
\n at '): e;
write(error);
Übrigens werden seit release 0.7.0 per parameter showErrors (auch) ohne dem try-catch blog ausgegeben und HTML.dump() funktioniert.
wildeuter