AddressBookWeb
Address book WEB application - (using Skylark)
Description
This example shows usage of SKYLARK technology to develop web application. More information about SKYLARK is available in U++ official documentation. If you would like to start playing with it, we recommended to begin with the tutorial. The application uses SQLite as a database engine. So, you don't need to install any SQL server to launch this example.
The application by default runs on following address: 127.0.0.1:8008 (localhost port 8008). If you want to see this page, just type above address in your browser.
Result (Web pages)

Adress book list
AddressBook.h
#ifndef _AdrBook_AdrBook_h_
#define _AdrBook_AdrBook_h_
#include <Skylark/Skylark.h>
#include <Skylark/Iml/Iml.h>
#include <plugin/sqlite3/Sqlite3.h>
using namespace Upp;
#define MODEL <AddressBookWeb/Model.sch>
#define SCHEMADIALECT <plugin/sqlite3/Sqlite3Schema.h>
#include <Sql/sch_header.h>
#endif
Main.cpp
#include "AddressBook.h"
#include <Sql/sch_schema.h>
#include <Sql/sch_source.h>
#define IMAGECLASS AdrBookImg
#define IMAGEFILE <AddressBookWeb/AdrBook.iml>
#include <Draw/iml_header.h>
#define IMAGECLASS AdrBookImg
#define IMAGEFILE <AddressBookWeb/AdrBook.iml>
#include <Draw/iml_source.h>
struct AdrBook : SkylarkApp {
void WorkThread();
AdrBook();
};
void OpenSQL(Sqlite3Session& sqlite3)
{
if(!sqlite3.Open(ConfigFile("db.sqlite3"))) {
LOG("Can't create or open database file\n");
Exit(1);
}
#ifdef _DEBUG
sqlite3.LogErrors();
sqlite3.SetTrace();
#endif
SQL = sqlite3;
}
void InitModel()
{
#ifdef _DEBUG
Sqlite3Session sqlsession;
OpenSQL(sqlsession);
SqlSchema sch(SQLITE3);
All_Tables(sch);
SqlPerformScript(sch.Upgrade());
SqlPerformScript(sch.Attributes());
sch.SaveNormal();
#endif
}
void AdrBook::WorkThread()
{
Sqlite3Session sqlite3;
OpenSQL(sqlite3);
RunThread();
}
AdrBook::AdrBook()
{
prefork = 0;
threads = 1; // Sqlite3 is not good with threads or concurrency...
#ifdef _DEBUG
use_caching = false;
#endif
}
// After starting the server, enter "127.0.0.1:8001" in your browser
CONSOLE_APP_MAIN
{
#ifdef _DEBUG
StdLogSetup(LOG_FILE|LOG_COUT);
Ini::skylark_log = true;
SKYLARKLOG("Active");
#endif
InitModel();
AdrBook().Run();
}
AdrBook.cpp
#include "AddressBook.h"
#include <Sql/sch_schema.h>
#include <Sql/sch_source.h>
#define IMAGECLASS AdrBookImg
#define IMAGEFILE <AddressBookWeb/AdrBook.iml>
#include <Draw/iml_header.h>
#define IMAGECLASS AdrBookImg
#define IMAGEFILE <AddressBookWeb/AdrBook.iml>
#include <Draw/iml_source.h>
struct AdrBook : SkylarkApp {
void WorkThread();
AdrBook();
};
void OpenSQL(Sqlite3Session& sqlite3)
{
if(!sqlite3.Open(ConfigFile("db.sqlite3"))) {
LOG("Can't create or open database file\n");
Exit(1);
}
#ifdef _DEBUG
sqlite3.LogErrors();
sqlite3.SetTrace();
#endif
SQL = sqlite3;
}
void InitModel()
{
#ifdef _DEBUG
SqlSchema sch(SQLITE3);
All_Tables(sch);
SqlPerformScript(sch.Upgrade());
SqlPerformScript(sch.Attributes());
sch.SaveNormal();
#endif
}
void AdrBook::WorkThread()
{
Sqlite3Session sqlite3;
OpenSQL(sqlite3);
RunThread();
}
AdrBook::AdrBook()
{
prefork = 0;
threads = 1; // Sqlite3 is not good with threads or concurrency...
#ifdef _DEBUG
use_caching = false;
#endif
}
// After starting the server, enter "127.0.0.1:8001" in your browser
CONSOLE_APP_MAIN
{
#ifdef _DEBUG
StdLogSetup(LOG_FILE|LOG_COUT);
Ini::skylark_log = true;
SKYLARKLOG("Active");
#endif
Sqlite3Session sqlsession;
OpenSQL(sqlsession);
InitModel();
AdrBook().Run();
}
Pages.icpp
#include "AddressBook.h"
SKYLARK(HomePage, "")
{
SqlBool where;
String s = http["search"];
if(!IsNull(s)) {
s << '%';
where = Like(FIRSTNAME, s) || Like(LASTNAME, s) || Like(EMAIL, s);
}
http("PERSON", Select(ID, FIRSTNAME, LASTNAME, EMAIL).From(PERSON)
.Where(where).OrderBy(LASTNAME, FIRSTNAME))
.RenderResult("AddressBookWeb/Index");
}
SKYLARK(CatchAll, "**")
{
http.Redirect(HomePage);
}
SKYLARK(SubmitNew, "submit/create:POST")
{
SQL * http.Insert(PERSON);
http.Redirect(HomePage);
}
SKYLARK(New, "person/create")
{
http("ACTION", SubmitNew)
.RenderResult("AddressBookWeb/Dialog");
}
SKYLARK(SubmitEdit, "submit/edit/*:POST")
{
SQL * http.Update(PERSON).Where(ID == http.Int(0));
http.Redirect(HomePage);
}
SKYLARK(Edit, "person/edit/*")
{
int id = http.Int(0);
http
(Select(FIRSTNAME, LASTNAME, EMAIL).From(PERSON).Where(ID == id))
("ID", id)
("ACTION", SubmitEdit, id)
.RenderResult("AddressBookWeb/Dialog");
}
SKYLARK(Delete, "person/delete/*")
{
SQL * Delete(PERSON).Where(ID == atoi(http[0]));
http.Redirect(HomePage);
}
Dialog.witz
#include Skylark/Base
#define BODY
<FORM action=$ACTION method="post" accept-charset="utf-8" enctype="multipart/form-data">
$post_identity()
<P>
First name: <INPUT type="text" name="firstname" value="$FIRSTNAME"><BR>
Last name: <INPUT type="text" name="lastname" value="$LASTNAME"><BR>
Email: <INPUT type="text" name="email" value="$EMAIL"><BR>
<INPUT type="submit" value="Send" name="OK"/><BR>
</P>
</FORM>
#define TITLE Please enter a person!
Index.witz
#include Skylark/Base
#define TITLE This is an experimental Web AddressBook application
#define BODY
<FORM action=$HomePage method="get" accept-charset="utf-8" enctype="multipart/form-data">
<P>
<INPUT type="text" name="search" value="$search">
<INPUT type="submit" value="Search">
</P>
</FORM>
<table border="1" id="persons">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
</tr>
$for(i in PERSON)
<tr>
<td>$i.FIRSTNAME</td>
<td>$i.LASTNAME</td>
<td>$i.EMAIL</td>
<td>
<a href=$Edit(i.ID)><img src=$Iml("AdrBookImg:Edit")/>Edit</a>
<a href=$Delete(i.ID)><img src=$Iml("AdrBookImg:Delete")/>Delete</a>
</td>
</tr>
$/
</table>
<p/>
<a href=$New><img src=$Iml("AdrBookImg:Plus")/>Insert new person</a>
Model.sch
TABLE_(PERSON)
INT_ (ID) PRIMARY_KEY AUTO_INCREMENT
STRING_ (FIRSTNAME, 200)
STRING_ (LASTNAME, 200)
STRING_ (EMAIL, 200)
END_TABLE
|