mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
Merge branch 'master' of https://github.com/ultimatepp/ultimatepp
This commit is contained in:
commit
fe3d1a5916
21 changed files with 1452 additions and 1117 deletions
|
|
@ -3,7 +3,7 @@
|
|||
using namespace Upp;
|
||||
|
||||
struct MyApp : TopWindow {
|
||||
virtual void Paint(Draw& w) override {
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), White());
|
||||
|
||||
w.DrawRect(10, 10, 60, 80, Green());
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using namespace Upp;
|
|||
struct MyApp : TopWindow {
|
||||
DropList font_list;
|
||||
|
||||
virtual void Paint(Draw& w) override {
|
||||
void Paint(Draw& w) override {
|
||||
const String text = "Programming is fun";
|
||||
Font fnt(~font_list, 60);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using namespace Upp;
|
|||
struct MyApp : TopWindow {
|
||||
Drawing drawing;
|
||||
|
||||
virtual void Paint(Draw& w) override {
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), White());
|
||||
w.DrawDrawing(10, 10, 50, 60, drawing);
|
||||
w.DrawDrawing(100, 10, 150, 100, drawing);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using namespace Upp;
|
|||
struct MyApp : TopWindow {
|
||||
Image image;
|
||||
|
||||
virtual void Paint(Draw& w) override {
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), Cyan());
|
||||
w.DrawImage(10, 10, image);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
using namespace Upp;
|
||||
|
||||
struct MyAppWindow : TopWindow {
|
||||
virtual void Paint(Draw& w) override {
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), SWhite());
|
||||
w.DrawText(20, 20, "Hello world!", Arial(30), Magenta);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,17 +6,17 @@ struct MyAppWindow : TopWindow {
|
|||
Point p;
|
||||
String text;
|
||||
|
||||
virtual void LeftDown(Point pos, dword flags) override {
|
||||
void LeftDown(Point pos, dword flags) override {
|
||||
p = pos;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
virtual void MouseMove(Point pos, dword flags) override {
|
||||
void MouseMove(Point pos, dword flags) override {
|
||||
text = Format("[%d:%d]", pos.x, pos.y);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
virtual void Paint(Draw& w) override {
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), SWhite);
|
||||
w.DrawText(p.x, p.y, text, Arial(20), Magenta);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ struct MyAppWindow : TopWindow {
|
|||
Break();
|
||||
}
|
||||
|
||||
virtual void RightDown(Point, dword) override {
|
||||
void RightDown(Point, dword) override {
|
||||
MenuBar::Execute(
|
||||
[=](Bar& bar) {
|
||||
bar.Add("Exit", [=] { Exit(); });
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ struct MyAppWindow : TopWindow {
|
|||
Break();
|
||||
}
|
||||
|
||||
virtual void RightDown(Point, dword) override {
|
||||
void RightDown(Point, dword) override {
|
||||
int result = Null;
|
||||
MenuBar menu;
|
||||
for(int i = 0; i < 10; i++)
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ using namespace Upp;
|
|||
struct MyCtrl : public Ctrl {
|
||||
int count = 0;
|
||||
|
||||
virtual void Paint(Draw& w) override {
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), White());
|
||||
w.DrawText(2, 2, AsString(count));
|
||||
}
|
||||
|
||||
virtual void LeftDown(Point, dword) override {
|
||||
void LeftDown(Point, dword) override {
|
||||
count++;
|
||||
Refresh();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ struct MyAppWindow : TopWindow {
|
|||
Zoomable().Sizeable().SetRect(0, 0, 550, 100);
|
||||
}
|
||||
|
||||
virtual void Paint(Draw& w) override {
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), SLtYellow);
|
||||
w.DrawText(20, 20, t_("Hello translation engine!"), Arial(30), Blue);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,18 +6,19 @@ using namespace Upp;
|
|||
#define IMAGEFILE <Image01/images.iml>
|
||||
#include <Draw/iml.h>
|
||||
|
||||
class MyApp : public TopWindow {
|
||||
public:
|
||||
virtual void Paint(Draw& draw);
|
||||
struct MyApp : TopWindow {
|
||||
MyApp() {
|
||||
const auto isz = MyImages::MyImage().GetSize();
|
||||
SetRect(0, 0, 100 + isz.cx, 100 + isz.cy);
|
||||
}
|
||||
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), SColorFace());
|
||||
w.DrawImage(50, 50, MyImages::MyImage());
|
||||
}
|
||||
};
|
||||
|
||||
void MyApp::Paint(Draw& w)
|
||||
{
|
||||
w.DrawRect(GetSize(), SColorFace());
|
||||
w.DrawImage(50, 50, MyImages::MyImage());
|
||||
}
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
MyApp().Sizeable().Run();
|
||||
MyApp().Run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,27 +6,27 @@ using namespace Upp;
|
|||
#define IMAGEFILE <Image02a/images.iml>
|
||||
#include <Draw/iml.h>
|
||||
|
||||
class MyApp : public TopWindow {
|
||||
public:
|
||||
virtual void Paint(Draw& draw);
|
||||
};
|
||||
|
||||
void MyApp::Paint(Draw& w)
|
||||
{
|
||||
w.DrawRect(GetSize(), SColorPaper());
|
||||
for(int i = 0; i < MyImages::GetCount(); i++) {
|
||||
w.DrawImage(50, 80 + 20 * i, MyImages::Get(i));
|
||||
w.DrawText(80, 80 + 20 * i, MyImages::GetId(i));
|
||||
struct MyApp : TopWindow {
|
||||
MyApp() {
|
||||
SetRect(0, 0, 170, 170);
|
||||
}
|
||||
w.DrawImage(20, 0, 50, 50, MyImages::Get(MyImages::I_Circle));
|
||||
w.DrawText(80, 0, AsString(MyImages::Find("Circle")));
|
||||
}
|
||||
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), SColorPaper());
|
||||
for(int i = 0; i < MyImages::GetCount(); i++) {
|
||||
w.DrawImage(50, 80 + 20 * i, MyImages::Get(i));
|
||||
w.DrawText(80, 80 + 20 * i, MyImages::GetId(i));
|
||||
}
|
||||
w.DrawImage(20, 0, 50, 50, MyImages::Get(MyImages::I_Circle));
|
||||
w.DrawText(80, 0, AsString(MyImages::Find("Circle")));
|
||||
}
|
||||
};
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
MyApp().Sizeable().Run();
|
||||
MyApp().Run();
|
||||
Image m = MyImages::Circle();
|
||||
MyImages::Set(MyImages::I_Circle, MyImages::Triangle());
|
||||
MyImages::Set(MyImages::I_Triangle, m);
|
||||
MyApp().Sizeable().Run();
|
||||
MyApp().Run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,24 +7,24 @@ using namespace Upp;
|
|||
#include <Draw/iml.h>
|
||||
|
||||
class MyApp : public TopWindow {
|
||||
Iml& iml;
|
||||
|
||||
public:
|
||||
virtual void Paint(Draw& draw);
|
||||
|
||||
MyApp(Iml& _iml) : iml(_iml) {}
|
||||
};
|
||||
|
||||
void MyApp::Paint(Draw& w)
|
||||
{
|
||||
w.DrawRect(GetSize(), SColorPaper());
|
||||
for(int i = 0; i < iml.GetCount(); i++) {
|
||||
w.DrawImage(50, 80 + 20 * i, iml.Get(i));
|
||||
w.DrawText(80, 80 + 20 * i, iml.GetId(i));
|
||||
MyApp(Iml& iml) : m_iml(iml) {
|
||||
SetRect(0, 0, 200, 200);
|
||||
}
|
||||
}
|
||||
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), SColorPaper());
|
||||
for(int i = 0; i < m_iml.GetCount(); i++) {
|
||||
w.DrawImage(50, 80 + 20 * i, m_iml.Get(i));
|
||||
w.DrawText(80, 80 + 20 * i, m_iml.GetId(i));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Iml& m_iml;
|
||||
};
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
MyApp(MyImages::Iml()).Sizeable().Run();
|
||||
MyApp(MyImages::Iml()).Run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,54 +5,49 @@ using namespace Upp;
|
|||
struct MyApp : public TopWindow {
|
||||
Image img;
|
||||
|
||||
virtual void Paint(Draw& w);
|
||||
virtual void LeftDown(Point p, dword keyflags);
|
||||
|
||||
typedef MyApp CLASSNAME;
|
||||
MyApp();
|
||||
};
|
||||
|
||||
MyApp::MyApp()
|
||||
{
|
||||
ImageBuffer ib(50, 50);
|
||||
for(int y = 0; y < 50; y++) {
|
||||
RGBA *l = ib[y];
|
||||
for(int x = 0; x < 50; x++) {
|
||||
if(y == 0 || y == 49 || x == 0 || x == 49)
|
||||
*l++ = Black();
|
||||
else {
|
||||
l->a = 2 * (x + y);
|
||||
l->r = 4 * x;
|
||||
l->g = 4 * y;
|
||||
l->b = 200;
|
||||
l++;
|
||||
MyApp() {
|
||||
ImageBuffer ib(50, 50);
|
||||
for(int y = 0; y < 50; y++) {
|
||||
RGBA *l = ib[y];
|
||||
for(int x = 0; x < 50; x++) {
|
||||
if(y == 0 || y == 49 || x == 0 || x == 49) {
|
||||
*l++ = Black();
|
||||
}
|
||||
else {
|
||||
l->a = 2 * (x + y);
|
||||
l->r = 4 * x;
|
||||
l->g = 4 * y;
|
||||
l->b = 200;
|
||||
l++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Premultiply(ib);
|
||||
img = ib;
|
||||
|
||||
SetRect(0, 0, img.GetSize().cx + 50, img.GetSize().cy + 35);
|
||||
}
|
||||
Premultiply(ib);
|
||||
img = ib;
|
||||
}
|
||||
|
||||
void MyApp::Paint(Draw& w)
|
||||
{
|
||||
w.DrawRect(GetSize(), White);
|
||||
w.DrawImage(10, 5, img);
|
||||
w.DrawImage(40, 25, img);
|
||||
}
|
||||
|
||||
void MyApp::LeftDown(Point p, dword keyflags)
|
||||
{
|
||||
ImageBuffer ib(img);
|
||||
for(int y = 15; y < 35; y++) {
|
||||
RGBA *l = ib[y];
|
||||
for(int x = 15; x < 35; x++)
|
||||
l[x] = 100 * Red();
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), White);
|
||||
w.DrawImage(10, 5, img);
|
||||
w.DrawImage(40, 25, img);
|
||||
}
|
||||
img = ib;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void LeftDown(Point p, dword keyflags) override {
|
||||
ImageBuffer ib(img);
|
||||
for(int y = 15; y < 35; y++) {
|
||||
RGBA *l = ib[y];
|
||||
for(int x = 15; x < 35; x++) {
|
||||
l[x] = 100 * Red();
|
||||
}
|
||||
}
|
||||
img = ib;
|
||||
Refresh();
|
||||
}
|
||||
};
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
MyApp().Sizeable().Run();
|
||||
MyApp().Run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,37 +6,32 @@ struct MyApp : public TopWindow {
|
|||
Image img;
|
||||
FileSel fs;
|
||||
|
||||
void Open();
|
||||
|
||||
virtual void Paint(Draw& w);
|
||||
virtual void LeftDown(Point, dword) { Open(); }
|
||||
|
||||
typedef MyApp CLASSNAME;
|
||||
MyApp();
|
||||
};
|
||||
|
||||
MyApp::MyApp()
|
||||
{
|
||||
fs.Type("Image file", "*.bmp;*.png;*.tif;*.tiff;*.jpg;*.jpeg;*.gif");
|
||||
Sizeable();
|
||||
}
|
||||
|
||||
void MyApp::Paint(Draw& w)
|
||||
{
|
||||
w.DrawRect(GetSize(), White);
|
||||
if(img)
|
||||
w.DrawImage(0, 0, img);
|
||||
else
|
||||
w.DrawText(0, 0, "No image loaded!", Arial(30).Italic());
|
||||
}
|
||||
|
||||
void MyApp::Open()
|
||||
{
|
||||
if(fs.ExecuteOpen("Choose the image file to open")) {
|
||||
img = StreamRaster::LoadFileAny(~fs);
|
||||
Refresh();
|
||||
MyApp() {
|
||||
fs.Type("Image file", "*.bmp;*.png;*.tif;*.tiff;*.jpg;*.jpeg;*.gif");
|
||||
Sizeable();
|
||||
}
|
||||
}
|
||||
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), White);
|
||||
if(img) {
|
||||
w.DrawImage(0, 0, img);
|
||||
}
|
||||
else {
|
||||
w.DrawText(0, 0, "No image loaded!", Arial(30).Italic());
|
||||
}
|
||||
}
|
||||
|
||||
void LeftDown(Point, dword) override {
|
||||
Open();
|
||||
}
|
||||
|
||||
void Open() {
|
||||
if(fs.ExecuteOpen("Choose the image file to open")) {
|
||||
img = StreamRaster::LoadFileAny(~fs);
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,25 +23,20 @@ struct BallMaker : ImageMaker {
|
|||
Color color;
|
||||
int r;
|
||||
|
||||
virtual String Key() const;
|
||||
virtual Image Make() const;
|
||||
String Key() const override {
|
||||
char h[sizeof(int) + 3];
|
||||
*(int *)h = r;
|
||||
h[sizeof(int)] = color.GetR();
|
||||
h[sizeof(int) + 1] = color.GetG();
|
||||
h[sizeof(int) + 2] = color.GetB();
|
||||
return String(h, sizeof(int) + 3);
|
||||
}
|
||||
|
||||
Image Make() const override {
|
||||
return CreateBall(r, color);
|
||||
}
|
||||
};
|
||||
|
||||
String BallMaker::Key() const
|
||||
{
|
||||
char h[sizeof(int) + 3];
|
||||
*(int *)h = r;
|
||||
h[sizeof(int)] = color.GetR();
|
||||
h[sizeof(int) + 1] = color.GetG();
|
||||
h[sizeof(int) + 2] = color.GetB();
|
||||
return String(h, sizeof(int) + 3);
|
||||
}
|
||||
|
||||
Image BallMaker::Make() const
|
||||
{
|
||||
return CreateBall(r, color);
|
||||
}
|
||||
|
||||
Image CreateBallCached(int r, Color color)
|
||||
{
|
||||
BallMaker m;
|
||||
|
|
@ -53,7 +48,7 @@ Image CreateBallCached(int r, Color color)
|
|||
struct MyApp : public TopWindow {
|
||||
bool cached;
|
||||
|
||||
virtual void Paint(Draw& w) {
|
||||
void Paint(Draw& w) override {
|
||||
w.DrawRect(GetSize(), White);
|
||||
for(int y = 0; y < 300; y += 30)
|
||||
for(int i = 10; i < 500; i += i / 3) {
|
||||
|
|
@ -62,7 +57,7 @@ struct MyApp : public TopWindow {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void LeftDown(Point, dword) {
|
||||
void LeftDown(Point, dword) override {
|
||||
cached = true;
|
||||
Title("Now cached - try to resize the window to see the speed");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,5 +18,5 @@ CONSOLE_APP_MAIN
|
|||
Sql sql(sqlite3);
|
||||
sql.Execute("select date('now')");
|
||||
while(sql.Fetch())
|
||||
Cout() << sql[0];
|
||||
Cout() << sql[0] << '\n';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,9 +224,8 @@ Upp;]&]
|
|||
[s0;l320;~~~32~32;C+75%- &]
|
||||
[s0;l320;~~~32~32;%- [*C@(0.0.255)+75 struct][C+75 MyAppWindow ][C@(0.0.255)+75 :][C+75
|
||||
TopWindow `{]&]
|
||||
[s0;l320;~~~32~32;%- [C+75 ][*_C@(0.0.255)+75 virtual][*_C+75 ][*_C@(0.0.255)+75 void][*_C+75
|
||||
Paint(Draw][*_C@(0.0.255)+75 `&][*_C+75 w) ][*_C@(0.0.255)+75 override][*_C+75
|
||||
`{]&]
|
||||
[s0;l320;~~~32~32;%- [C+75 ][*_C@(0.0.255)+75 void][*_C+75 Paint(Draw][*_C@(0.0.255)+75 `&
|
||||
][*_C+75 w) ][*_C@(0.0.255)+75 override][*_C+75 `{]&]
|
||||
[s0;l320;~~~32~32;%- [C+75 ][*_C+75 w][*_C@(0.0.255)+75 .][*_C+75 DrawRect(GetSize(),
|
||||
SWhite());]&]
|
||||
[s0;l320;~~~32~32;%- [C+75 ][*_C+75 w][*_C@(0.0.255)+75 .][*_C+75 DrawText(][*_C@3+75 2
|
||||
|
|
@ -278,25 +277,24 @@ TopWindow `{]&]
|
|||
[s0;l320;%- [C+75 Point p;]&]
|
||||
[s0;l320;%- [C+75 String text;]&]
|
||||
[s0;l320;C+75%- &]
|
||||
[s0;l320;%- [*C+75 ][*_C@(0.0.255)+75 virtual][*_C+75 ][*_C@(0.0.255)+75 void][*_C+75
|
||||
LeftDown(Point pos, ][*_C@(0.128.128)+75 dword][*_C+75 flags) ][*_C@(0.0.255)+75 overr
|
||||
ide][*_C+75 `{]&]
|
||||
[s0;l320;%- [*C+75 ][*_C@(0.0.255)+75 void][*_C+75 LeftDown(Point
|
||||
pos, ][*_C@(0.128.128)+75 dword][*_C+75 flags) ][*_C@(0.0.255)+75 override][*_C+75
|
||||
`{]&]
|
||||
[s0;l320;%- [*C+75 ][*_C+75 p ][*_C@(0.0.255)+75 `=][*_C+75 pos;]&]
|
||||
[s0;l320;%- [*C+75 ][*_C+75 Refresh();]&]
|
||||
[s0;l320;%- [*C+75 ][*_C+75 `}]&]
|
||||
[s0;l320;*C+75%- &]
|
||||
[s0;l320;%- [*C+75 ][*_C@(0.0.255)+75 virtual][*_C+75 ][*_C@(0.0.255)+75 void][*_C+75
|
||||
MouseMove(Point pos, ][*_C@(0.128.128)+75 dword][*_C+75 flags) ][*_C@(0.0.255)+75 over
|
||||
ride][*_C+75 `{]&]
|
||||
[s0;l320;%- [*C+75 ][*_C@(0.0.255)+75 void][*_C+75 MouseMove(Point
|
||||
pos, ][*_C@(0.128.128)+75 dword][*_C+75 flags) ][*_C@(0.0.255)+75 override][*_C+75
|
||||
`{]&]
|
||||
[s0;l320;%- [*C+75 ][*_C+75 text ][*_C@(0.0.255)+75 `=][*_C+75 Format(][*_C@3+75 `"`[][*_C@(0.0.255)+75 %
|
||||
d][*_C@3+75 :][*_C@(0.0.255)+75 %d][*_C@3+75 `]`"][*_C+75 , pos][*_C@(0.0.255)+75 .][*_C+75 x,
|
||||
pos][*_C@(0.0.255)+75 .][*_C+75 y);]&]
|
||||
[s0;l320;%- [*C+75 ][*_C+75 Refresh();]&]
|
||||
[s0;l320;%- [*C+75 ][*_C+75 `}]&]
|
||||
[s0;l320;C+75%- &]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 virtual][C+75 ][*C@(0.0.255)+75 void][C+75
|
||||
Paint(Draw][C@(0.0.255)+75 `&][C+75 w) ][*C@(0.0.255)+75 override][C+75
|
||||
`{]&]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 void][C+75 Paint(Draw][C@(0.0.255)+75 `&][C+75
|
||||
w) ][*C@(0.0.255)+75 override][C+75 `{]&]
|
||||
[s0;l320;%- [C+75 w][C@(0.0.255)+75 .][C+75 DrawRect(GetSize(),
|
||||
SWhite);]&]
|
||||
[s0;l320;%- [C+75 w][C@(0.0.255)+75 .][C+75 DrawText(p][C@(0.0.255)+75 .][C+75 x,
|
||||
|
|
@ -502,9 +500,8 @@ MyApp?`"][C+75 ))]&]
|
|||
[s0;l320;%- [C+75 Break();]&]
|
||||
[s0;l320;%- [C+75 `}]&]
|
||||
[s0;l320;C+75%- &]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 virtual][C+75 ][*C@(0.0.255)+75 void][C+75
|
||||
RightDown(Point, ][C@(0.128.128)+75 dword][C+75 ) ][*C@(0.0.255)+75 override][C+75
|
||||
`{]&]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 void][C+75 RightDown(Point, ][C@(0.128.128)+75 dword
|
||||
][C+75 ) ][*C@(0.0.255)+75 override][C+75 `{]&]
|
||||
[s0;l320;%- [C+75 ][*_C+75 MenuBar][*_C@(0.0.255)+75 `::][*_C+75 Execute(]&]
|
||||
[s0;l320;%- [C+75 ][*_C@(0.0.255)+75 `[`=`]][*_C+75 (Bar][*_C@(0.0.255)+75 `&][*_C+75
|
||||
bar) `{]&]
|
||||
|
|
@ -550,9 +547,8 @@ MyApp?`"][C+75 ))]&]
|
|||
[s0;l320;%- [C+75 Break();]&]
|
||||
[s0;l320;%- [C+75 `}]&]
|
||||
[s0;l320;C+75%- &]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 virtual][C+75 ][*C@(0.0.255)+75 void][C+75
|
||||
RightDown(Point, ][C@(0.128.128)+75 dword][C+75 ) ][*C@(0.0.255)+75 override][C+75
|
||||
`{]&]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 void][C+75 RightDown(Point, ][C@(0.128.128)+75 dword
|
||||
][C+75 ) ][*C@(0.0.255)+75 override][C+75 `{]&]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 int][C+75 ][*_C+75 result][*C+75
|
||||
][C@(0.0.255)+75 `=][C+75 ][C@(0.128.128)+75 Null][C+75 ;]&]
|
||||
[s0;l320;%- [C+75 ][*_C+75 MenuBar menu][C+75 ;]&]
|
||||
|
|
@ -1075,17 +1071,12 @@ to respond to platform setting of GUI font, U`+`+ provides functions
|
|||
to zoom coordinates accordingly. Such zooming scale distances
|
||||
by the ratio of current standard GUI font size to design font
|
||||
size (which is based on old Win95 standard font size). Functions
|
||||
Zx and Zy scale the horizontal or vertical distance. Logical
|
||||
coordinate methods that end with Z (like LeftPos[* Z]) are then
|
||||
scaling the values with these functions.&]
|
||||
[* Zx] and [* Zy] scale the horizontal or vertical distance. Logical
|
||||
coordinate methods that end with [* Z] (like [* LeftPosZ ]or [* TopPosZ])
|
||||
are then scaling the values with these functions.&]
|
||||
[s5; &]
|
||||
[s7; GUI`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|MyAppWindow app;&]
|
||||
[s7; -|app.Run();&]
|
||||
[s7; `}&]
|
||||
[s0;l320;%- [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 CtrlLib][C@(0.0.255)+75 /
|
||||
][C+75 CtrlLib][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s7;%- [@(128.0.255) #include][@0 ][@(0.0.255) <][@0 CtrlLib][@(0.0.255) /][@0 CtrlLib][@(0.0.255) .
|
||||
][@0 h][@(0.0.255) >]&]
|
||||
[s0;l320;C+75%- &]
|
||||
[s0;l320;%- [*C@(0.0.255)+75 using][C+75 ][*C@(0.0.255)+75 namespace][C+75
|
||||
Upp;]&]
|
||||
|
|
@ -1555,8 +1546,7 @@ react to Enter and Esc keys and add specific visual appearance.&]
|
|||
[* CtrlLayoutCancel], [* CtrlLayoutOKCancel ]etc. template functions
|
||||
that both [^topic`:`/`/CtrlCore`/src`/Layout`_en`-us^ setup layout
|
||||
and assign] Acceptors and Rejectors!&]
|
||||
[s5; &]
|
||||
[s7; [@(28.127.0) // main.cpp]&]
|
||||
[s5; [/ main.cpp:]&]
|
||||
[s0;l320;~~~>32;%- [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 CtrlLib][C@(0.0.255)+75 /
|
||||
][C+75 CtrlLib][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320;~~~>32;C+75%- &]
|
||||
|
|
@ -1585,8 +1575,8 @@ d][C@(0.0.255)+75 /][C+75 myapp][C@(0.0.255)+75 .][C+75 lay][C@(0.0.255)+75 >]&]
|
|||
[s0;l320;~~~>32;%- [C+75 Exclamation(][C@3+75 `"Canceled`"][C+75 );]&]
|
||||
[s0;l320;~~~>32;%- [C+75 `}]&]
|
||||
[s0;l320;~~~>32;%- [C+75 `}]&]
|
||||
[s7; &]
|
||||
[s7; [@(28.127.0) // myapp.lay]&]
|
||||
[s5;%- &]
|
||||
[s5; [/ myapp.lay:]&]
|
||||
[s0;l320;%- [*C@(0.0.255)+75 LAYOUT][C+75 (MyAppLayout, ][C@3+75 148][C+75 ,
|
||||
][C@3+75 64][C+75 )]&]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 ITEM][C+75 (Upp][C@(0.0.255)+75 `::][C+75 EditDate,
|
||||
|
|
@ -1601,7 +1591,7 @@ opPosZ(][C@3+75 32][C+75 , ][C@3+75 24][C+75 ))]&]
|
|||
][C+75 )][C@(0.0.255)+75 .][C+75 LeftPosZ(][C@3+75 76][C+75 , ][C@3+75 64][C+75 )][C@(0.0.255)+75 .
|
||||
][C+75 TopPosZ(][C@3+75 32][C+75 , ][C@3+75 24][C+75 ))]&]
|
||||
[s0;l320;%- [*C@(0.0.255)+75 END][C@(0.0.255)+75 `_][*C@(0.0.255)+75 LAYOUT]&]
|
||||
[s0; &]
|
||||
[s5; &]
|
||||
[s7;@(28.127.0) &]
|
||||
[s7;
|
||||
@@rawimage:697&461
|
||||
|
|
@ -1623,18 +1613,16 @@ Ctrl `{]&]
|
|||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 int][C+75 count ][C@(0.0.255)+75 `=][C+75
|
||||
][C@3+75 0][C+75 ;]&]
|
||||
[s0;l320;C+75%- &]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 virtual][C+75 ][*C@(0.0.255)+75 void][C+75
|
||||
Paint(Draw][C@(0.0.255)+75 `&][C+75 w) ][*C@(0.0.255)+75 override][C+75
|
||||
`{]&]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 void][C+75 Paint(Draw][C@(0.0.255)+75 `&][C+75
|
||||
w) ][*C@(0.0.255)+75 override][C+75 `{]&]
|
||||
[s0;l320;%- [C+75 w][C@(0.0.255)+75 .][C+75 DrawRect(GetSize(),
|
||||
White());]&]
|
||||
[s0;l320;%- [C+75 w][C@(0.0.255)+75 .][C+75 DrawText(][C@3+75 2][C+75 ,
|
||||
][C@3+75 2][C+75 , AsString(count));]&]
|
||||
[s0;l320;%- [C+75 `}]&]
|
||||
[s0;l320;C+75%- &]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 virtual][C+75 ][*C@(0.0.255)+75 void][C+75
|
||||
LeftDown(Point, ][C@(0.128.128)+75 dword][C+75 ) ][*C@(0.0.255)+75 override][C+75
|
||||
`{]&]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 void][C+75 LeftDown(Point, ][C@(0.128.128)+75 dword][C+75 )
|
||||
][*C@(0.0.255)+75 override][C+75 `{]&]
|
||||
[s0;l320;%- [C+75 count][C@(0.0.255)+75 `+`+][C+75 ;]&]
|
||||
[s0;l320;%- [C+75 Refresh();]&]
|
||||
[s0;l320;%- [C+75 `}]&]
|
||||
|
|
@ -1754,8 +1742,7 @@ create an application that will support multiple locales. For
|
|||
this purpose, we will pick up one of the previous example in
|
||||
which simple text is displayed inside the window, and we will
|
||||
add translation support to it:&]
|
||||
[s0; &]
|
||||
[s7; [@(28.127.0) // main.cpp]&]
|
||||
[s5; [/ main.cpp:]&]
|
||||
[s7;%- [@(128.0.255) #include][@0 ][@(0.0.255) <][@0 CtrlLib][@(0.0.255) /][@0 CtrlLib][@(0.0.255) .
|
||||
][@0 h][@(0.0.255) >]&]
|
||||
[s0;l320;C+75%- &]
|
||||
|
|
@ -1778,9 +1765,8 @@ My application`"][*_C@(0.128.128)$(255.255.192)+75 )][C+75 );]&]
|
|||
etRect(][C@3+75 0][C+75 , ][C@3+75 0][C+75 , ][C@3+75 550][C+75 , ][C@3+75 100][C+75 );]&]
|
||||
[s0;l320;%- [C+75 `}]&]
|
||||
[s0;l320;%- [C+75 ]&]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 virtual][C+75 ][*C@(0.0.255)+75 void][C+75
|
||||
Paint(Draw][C@(0.0.255)+75 `&][C+75 w) ][*C@(0.0.255)+75 override][C+75
|
||||
`{]&]
|
||||
[s0;l320;%- [C+75 ][*C@(0.0.255)+75 void][C+75 Paint(Draw][C@(0.0.255)+75 `&][C+75
|
||||
w) ][*C@(0.0.255)+75 override][C+75 `{]&]
|
||||
[s0;l320;%- [C+75 w][C@(0.0.255)+75 .][C+75 DrawRect(GetSize(),
|
||||
SLtYellow);]&]
|
||||
[s0;l320;%- [C+75 w][C@(0.0.255)+75 .][C+75 DrawText(][C@3+75 20][C+75 ,
|
||||
|
|
@ -1828,12 +1814,12 @@ our users use.&]
|
|||
[s5; The generated file with translated entries is located below.
|
||||
For the purpose of this section we used electronic translator,
|
||||
so for any errors we are sorry.&]
|
||||
[s0; &]
|
||||
[s5; [/ Gui23.t:]&]
|
||||
[s7; [@(28.127.0) // Gui23.t]&]
|
||||
[s0;l320;%- [C+75 #ifdef `_MSC`_VER]&]
|
||||
[s0;l320;%- [C+75 #pragma setlocale(][C@3+75 `"C`"][C+75 )]&]
|
||||
[s0;l320;%- [C+75 #endif]&]
|
||||
[s0;l320;%- [/C+75 // main.cpp]&]
|
||||
[s0;l320;%- [/C@4+75 // main.cpp]&]
|
||||
[s0;l320;C+75%- &]
|
||||
[s0;l320;%- [*C@(0.0.255)+75 T][C@(0.0.255)+75 `_][C+75 (][C@3+75 `"My application`"][C+75 )]&]
|
||||
[s0;l320;%- [C@(0.128.128)+75 csCZ][C+75 (][C@3+75 `"Moje aplikace`"][C+75 )]&]
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -21,57 +21,65 @@ topic "SQL Tutorial";
|
|||
[C2 $$20,20#70211524482531209251820423858195:class`-nested]
|
||||
[b50;2 $$21,21#03324558446220344731010354752573:Par]
|
||||
[2 $$0,0#00000000000000000000000000000000:Default]
|
||||
[{_}%EN-US
|
||||
[s2; SQL Tutorial&]
|
||||
[s3; Table of contents&]
|
||||
[s0; &]
|
||||
[s0; [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#1^ 1. SqlSession,
|
||||
[{_}
|
||||
[s2;%% SQL Tutorial&]
|
||||
[s3;%% Table of contents&]
|
||||
[s0;%% &]
|
||||
[s0;%% [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#1^ 1. SqlSession,
|
||||
Sql, opening database connection]&]
|
||||
[s0; [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#2^ 2. Using global
|
||||
[s0;%% [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#2^ 2. Using global
|
||||
main database, executing statements with parameters, getting
|
||||
resultset info]&]
|
||||
[s0; [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#3^ 3. Using SqlExp]&]
|
||||
[s0; [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#4^ 4. Schema file]&]
|
||||
[s0; [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#5^ 5. Using schema
|
||||
[s0;%% [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#3^ 3. Using SqlExp]&]
|
||||
[s0;%% [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#4^ 4. Schema file]&]
|
||||
[s0;%% [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#5^ 5. Using schema
|
||||
file to define SqlId constants]&]
|
||||
[s0; [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#6^ 6. Using structures
|
||||
[s0;%% [^topic`:`/`/Sql`/srcdoc`/tutorial`$en`-us`#6^ 6. Using structures
|
||||
defined by schema files]&]
|
||||
[s0; &]
|
||||
[s3;:1: 1. SqlSession, Sql, opening database connection&]
|
||||
[s5; SqlSession derived objects represent database connection. Each
|
||||
SQL database (Sqlite3, Microsoft SQL, Oracle, MySQL, PostgreSQL)
|
||||
[s0;%% &]
|
||||
[s3;:1:%% 1. SqlSession, Sql, opening database connection&]
|
||||
[s5;%% SqlSession derived objects represent database connection.
|
||||
Each SQL database (Sqlite3, Microsoft SQL, Oracle, MySQL, PostgreSQL)
|
||||
has its own session class derived from SqlSession. Sql class
|
||||
is used to issue SQL statements and retrieve results:&]
|
||||
[s7; &]
|
||||
[s7; #include <Core/Core.h>&]
|
||||
[s7; #include <plugin/sqlite3/Sqlite3.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; CONSOLE`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|[* Sqlite3Session ]sqlite3;&]
|
||||
[s7; -|if(!sqlite3.[* Open](ConfigFile(`"simple.db`"))) `{&]
|
||||
[s7; -|-|Cout() << `"Can`'t create or open database file`\n`";&]
|
||||
[s7; -|-|return;&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|&]
|
||||
[s7; #ifdef `_DEBUG&]
|
||||
[s7; -|sqlite3.[* SetTrace();]&]
|
||||
[s7; #endif&]
|
||||
[s7; &]
|
||||
[s7; -|[* Sql] sql(sqlite3);&]
|
||||
[s7; -|sql.[* Execute](`"select date(`'now`')`");&]
|
||||
[s7; -|while(sql.[* Fetch]())&]
|
||||
[s7; -|-|Cout() << [* sql`[0`] ]<< `'`\n`' << ;&]
|
||||
[s7; `}&]
|
||||
[s7; &]
|
||||
[s5; In this tutorial, we are using Sqlite3 database. The connection
|
||||
[s5;%% &]
|
||||
[s7;l320; [@(128.0.255) #include][@0 ][@(0.0.255) <][@0 Core][@(0.0.255) /][@0 Core][@(0.0.255) .][@0 h
|
||||
][@(0.0.255) >]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 plugin][C@(0.0.255)+75 /][C+75 s
|
||||
qlite3][C@(0.0.255)+75 /][C+75 Sqlite3][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [*C@(0.0.255)+75 using][C+75 ][*C@(0.0.255)+75 namespace][C+75
|
||||
Upp;]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 CONSOLE`_APP`_MAIN]&]
|
||||
[s0;l320; [C+75 `{]&]
|
||||
[s0;l320; [C+75 ][*_C+75 Sqlite3Session][C+75 sqlite3;]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 if][C+75 (][C@(0.0.255)+75 !][C+75 sqlite3][C@(0.0.255)+75 .
|
||||
][*_C+75 Open][C+75 (ConfigFile(][C@3+75 `"simple.db`"][C+75 ))) `{]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"Can`'t
|
||||
create or open database file][C@(0.0.255)+75 `\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 ][*_C@(128.0.255)+75 return][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s0;l320; [C+75 ]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #ifdef][C+75 `_DEBUG]&]
|
||||
[s0;l320; [C+75 sqlite3][C@(0.0.255)+75 .][*_C+75 SetTrace][C+75 ();]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #endif]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 ][*_C+75 Sql][C+75 sql(sqlite3);]&]
|
||||
[s0;l320; [C+75 sql][C@(0.0.255)+75 .][*_C+75 Execute][C+75 (][C@3+75 `"select
|
||||
date(`'now`')`"][C+75 );]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 while][C+75 (sql][C@(0.0.255)+75 .][*_C+75 Fetch][C+75 ())]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 ][*_C+75 sql][*_C@(0.0.255)+75 `[][*_C@3+75 0
|
||||
][*_C@(0.0.255)+75 `]][C+75 ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `'][C@(0.0.255)+75 `\n][C@3+75 `'
|
||||
][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s5;%% &]
|
||||
[s5;%% In this tutorial, we are using Sqlite3 database. The connection
|
||||
method varies with database; in this case it is done using [* Open
|
||||
]statement.&]
|
||||
[s5; [* SetTrace ]is useful in debug mode `- all issued SQL statements
|
||||
[s5;%% [* SetTrace ]is useful in debug mode `- all issued SQL statements
|
||||
and SQL errors are logged in standard U`+`+ log.&]
|
||||
[s5; Each [* Sql] instance has to be associated to some SqlSession
|
||||
[s5;%% Each [* Sql] instance has to be associated to some SqlSession
|
||||
`- it is passed as constructor parameter (parameter`-less Sql
|
||||
constructor uses global session, more on that in section 2.).
|
||||
To execute SQL statements, use [* Execute]. If executed statement
|
||||
|
|
@ -79,56 +87,75 @@ is Select, it may return a result set, which is retrieved using
|
|||
[* Fetch]. Columns of result set are then accessed by Sql`::operator`[`]
|
||||
using index of column (starts with 0). Values are returned as
|
||||
Value type.&]
|
||||
[s5; &]
|
||||
[s3;:2: 2. Using global main database, executing statements with
|
||||
[s5;%% &]
|
||||
[s3;:2:%% 2. Using global main database, executing statements with
|
||||
parameters, getting resultset info&]
|
||||
[s5; Most applications need to work with just single database backend,
|
||||
[s5;%% Most applications need to work with just single database backend,
|
||||
therefore repeating SqlSession parameter in all Sql declarations
|
||||
would be tedious.&]
|
||||
[s5; To this end U`+`+ supports concept of `"main database`" which
|
||||
[s5;%% To this end U`+`+ supports concept of `"main database`" which
|
||||
is represented by [* SQL] variable. [* SQL] is of Sql type. When
|
||||
any other Sql variable is created with default constructor (no
|
||||
session parameter provided), it uses the same session as the
|
||||
one the SQL is bound to. To assign session to global SQL, use
|
||||
operator`=:&]
|
||||
[s7; #include <Core/Core.h>&]
|
||||
[s7; #include <plugin/sqlite3/Sqlite3.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; CONSOLE`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|Sqlite3Session sqlite3;&]
|
||||
[s7; -|if(!sqlite3.Open(ConfigFile(`"simple.db`"))) `{&]
|
||||
[s7; -|-|Cout() << `"Can`'t create or open database file`\n`";&]
|
||||
[s7; -|-|return;&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|&]
|
||||
[s7; #ifdef `_DEBUG&]
|
||||
[s7; -|sqlite3.SetTrace();&]
|
||||
[s7; #endif&]
|
||||
[s7; &]
|
||||
[s7; -|[* SQL `= ]sqlite3;&]
|
||||
[s7; -|&]
|
||||
[s7; -|[* SQL.]Execute(`"drop table TEST`");&]
|
||||
[s7; -|SQL.ClearError();&]
|
||||
[s7; -|SQL.Execute(`"create table TEST (A INTEGER, B TEXT)`");&]
|
||||
[s7; &]
|
||||
[s7; -|for(int i `= 0; i < 10; i`+`+)&]
|
||||
[s7; -|-|SQL.[* Execute](`"insert into TEST(A, B) values ([* ?], [* ?])`",
|
||||
i, AsString(3 `* i));&]
|
||||
[s7; &]
|
||||
[s7; -|Sql sql;&]
|
||||
[s7; -|sql.Execute(`"select `* from TEST`");&]
|
||||
[s7; -|for(int i `= 0; i < sql.[* GetColumns](); i`+`+)&]
|
||||
[s7; -|-|Cout() << sql.[* GetColumnInfo](i).[* name ]<< `'`\n`';&]
|
||||
[s7; -|while(sql.Fetch())&]
|
||||
[s7; -|-|Cout() << sql`[0`] << `" `\`'`" << sql`[1`] << `"`\`'`\n`";&]
|
||||
[s7; `}&]
|
||||
[s7; &]
|
||||
[s5; As global [* SQL] is regular Sql variable too, it can be used
|
||||
[s5; &]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 Core][C@(0.0.255)+75 /][C+75 C
|
||||
ore][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 plugin][C@(0.0.255)+75 /][C+75 s
|
||||
qlite3][C@(0.0.255)+75 /][C+75 Sqlite3][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [*C@(0.0.255)+75 using][C+75 ][*C@(0.0.255)+75 namespace][C+75
|
||||
Upp;]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 CONSOLE`_APP`_MAIN]&]
|
||||
[s0;l320; [C+75 `{]&]
|
||||
[s0;l320; [C+75 Sqlite3Session sqlite3;]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 if][C+75 (][C@(0.0.255)+75 !][C+75 sqlite3][C@(0.0.255)+75 .
|
||||
][C+75 Open(ConfigFile(][C@3+75 `"simple.db`"][C+75 ))) `{]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"Can`'t
|
||||
create or open database file][C@(0.0.255)+75 `\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 ][*_C@(128.0.255)+75 return][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s0;l320; [C+75 ]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #ifdef][C+75 `_DEBUG]&]
|
||||
[s0;l320; [C+75 sqlite3][C@(0.0.255)+75 .][C+75 SetTrace();]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #endif]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 ][*_C+75 SQL][C+75 ][C@(0.0.255)+75 `=][C+75 sqlite3;]&]
|
||||
[s0;l320; [C+75 ]&]
|
||||
[s0;l320; [C+75 ][*_C+75 SQL][C@(0.0.255)+75 .][C+75 Execute(][C@3+75 `"drop
|
||||
table TEST`"][C+75 );]&]
|
||||
[s0;l320; [C+75 SQL][C@(0.0.255)+75 .][C+75 ClearError();]&]
|
||||
[s0;l320; [C+75 SQL][C@(0.0.255)+75 .][C+75 Execute(][C@3+75 `"create
|
||||
table TEST (A INTEGER, B TEXT)`"][C+75 );]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 for][C+75 (][*C@(0.0.255)+75 int][C+75
|
||||
i ][C@(0.0.255)+75 `=][C+75 ][C@3+75 0][C+75 ; i ][C@(0.0.255)+75 <][C+75
|
||||
][C@3+75 10][C+75 ; i][C@(0.0.255)+75 `+`+][C+75 )]&]
|
||||
[s0;l320; [C+75 SQL][C@(0.0.255)+75 .][*_C+75 Execute][C+75 (][C@3+75 `"insert
|
||||
into TEST(A, B) values (?, ?)`"][C+75 , i, AsString(][C@3+75 3][C+75
|
||||
][C@(0.0.255)+75 `*][C+75 i));]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 Sql sql;]&]
|
||||
[s0;l320; [C+75 sql][C@(0.0.255)+75 .][C+75 Execute(][C@3+75 `"select
|
||||
`* from TEST`"][C+75 );]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 for][C+75 (][*C@(0.0.255)+75 int][C+75
|
||||
i ][C@(0.0.255)+75 `=][C+75 ][C@3+75 0][C+75 ; i ][C@(0.0.255)+75 <][C+75
|
||||
sql][C@(0.0.255)+75 .][*_C+75 GetColumns][C+75 (); i][C@(0.0.255)+75 `+`+][C+75 )]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 sql][C@(0.0.255)+75 .][*_C+75 GetColu
|
||||
mnInfo(i)][*_C@(0.0.255)+75 .][*_C+75 name][C+75 ][C@(0.0.255)+75 <<][C+75
|
||||
][C@3+75 `'][C@(0.0.255)+75 `\n][C@3+75 `'][C+75 ;]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 while][C+75 (sql][C@(0.0.255)+75 .][C+75 Fetch())]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 sql][C@(0.0.255)+75 `[][C@3+75 0][C@(0.0.255)+75 `]
|
||||
][C+75 ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `" ][C@(0.0.255)+75 `\`'][C@3+75 `"][C+75
|
||||
][C@(0.0.255)+75 <<][C+75 sql][C@(0.0.255)+75 `[][C@3+75 1][C@(0.0.255)+75 `]][C+75
|
||||
][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"][C@(0.0.255)+75 `\`'`\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s5;l320;%% &]
|
||||
[s5;%% As global [* SQL] is regular Sql variable too, it can be used
|
||||
to issue SQL statements.&]
|
||||
[s5; [/ Warning: While it is possible to issue ][*/ select][/ statements
|
||||
[s5;%% [/ Warning: While it is possible to issue ][*/ select][/ statements
|
||||
through ][*/ SQL][/ , based on experience this is not recommended
|
||||
`- way too often result set of ][*/ select][/ is canceled by issuing
|
||||
some other command, e.g. in routine called as part of Fetch loop.
|
||||
|
|
@ -136,246 +163,316 @@ One exception to this rule is using SQL`::operator% to fetch single
|
|||
value like ][*C@5+75 String txt `= SQL % Select(TEXT).From(DOCTEMPLATE).Where(ID
|
||||
`=`= id); ][/ (see further tutorial topics for detailed explanation
|
||||
of this code).]&]
|
||||
[s5; To get information about result set columns, you can use [* GetColumns
|
||||
[s5;%% To get information about result set columns, you can use [* GetColumns
|
||||
]to retrieve the number of columns and [* GetColumnInfo] to retrieve
|
||||
information about columns `- returns [* SqlColumnInfo] reference
|
||||
with information like name or type of column.&]
|
||||
[s5; &]
|
||||
[s3;:3: 3. Using SqlExp&]
|
||||
[s5; U`+`+ contains an unique feature, `"SqlExp`". This is a mechanism
|
||||
[s5;%% &]
|
||||
[s3;:3:%% 3. Using SqlExp&]
|
||||
[s5;%% U`+`+ contains an unique feature, `"SqlExp`". This is a mechanism
|
||||
where you construct SQL statements as C`+`+ expressions (using
|
||||
heavily overloaded operators).&]
|
||||
[s5; There are three advantages to this approach:&]
|
||||
[s5;l160;i150;O0; SQL statements are at least partially checked at
|
||||
compile time&]
|
||||
[s5;l160;i150;O0; As such statements are yet to be interpreted, it
|
||||
is possible to hide some differences between DB engines&]
|
||||
[s5;l160;i150;O0; It is much easier to create complex dynamic SQL
|
||||
[s5;%% There are three advantages to this approach:&]
|
||||
[s5;l160;i150;O0;%% SQL statements are at least partially checked
|
||||
at compile time&]
|
||||
[s5;l160;i150;O0;%% As such statements are yet to be interpreted,
|
||||
it is possible to hide some differences between DB engines&]
|
||||
[s5;l160;i150;O0;%% It is much easier to create complex dynamic SQL
|
||||
statements&]
|
||||
[s5; Database entity identifiers (like table or column names) can
|
||||
[s5;%% Database entity identifiers (like table or column names) can
|
||||
be defined as [* SqlId] type. For the complete lest of supported
|
||||
SQL statements, see [^topic`:`/`/Sql`/src`/SqlExp`$en`-us^ SqlExp
|
||||
in examples].&]
|
||||
[s7; #include <Core/Core.h>&]
|
||||
[s7; #include <plugin/sqlite3/Sqlite3.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; CONSOLE`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|Sqlite3Session sqlite3;&]
|
||||
[s7; -|if(!sqlite3.Open(ConfigFile(`"simple.db`"))) `{&]
|
||||
[s7; -|-|Cout() << `"Can`'t create or open database file`\n`";&]
|
||||
[s7; -|-|return;&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|&]
|
||||
[s7; #ifdef `_DEBUG&]
|
||||
[s7; -|sqlite3.SetTrace();&]
|
||||
[s7; #endif&]
|
||||
[s7; &]
|
||||
[s7; -|SQL `= sqlite3;&]
|
||||
[s7; -|&]
|
||||
[s7; -|SQL.Execute(`"drop table TEST`");&]
|
||||
[s7; -|SQL.ClearError();&]
|
||||
[s7; -|SQL.Execute(`"create table TEST (A INTEGER, B TEXT)`");&]
|
||||
[s7; &]
|
||||
[s7; -|[* SqlId] A(`"A`"), B(`"B`"), TEST(`"TEST`");&]
|
||||
[s7; &]
|
||||
[s7; -|for(int i `= 0; i < 10; i`+`+)&]
|
||||
[s7; -|-|SQL [* `* Insert(TEST)(A, ]i[* )(B, ]AsString(3 `* i)[* );]&]
|
||||
[s7; &]
|
||||
[s7; -|Sql sql;&]
|
||||
[s7; -|sql [* `* Select(A, B).From(TEST);]&]
|
||||
[s7; -|while(sql.Fetch())&]
|
||||
[s7; -|-|Cout() << [* sql`[A`]] << `" `\`'`" << [* sql`[B`]] << `"`\`'`\n`";&]
|
||||
[s7; `}&]
|
||||
[s7; &]
|
||||
[s5; SqlId identifiers can be also used as parameter of Sql`::operator`[`]
|
||||
[s5;%% &]
|
||||
[s7;l320; [@(128.0.255) #include][@0 ][@(0.0.255) <][@0 Core][@(0.0.255) /][@0 Core][@(0.0.255) .][@0 h
|
||||
][@(0.0.255) >]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 plugin][C@(0.0.255)+75 /][C+75 s
|
||||
qlite3][C@(0.0.255)+75 /][C+75 Sqlite3][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [*C@(0.0.255)+75 using][C+75 ][*C@(0.0.255)+75 namespace][C+75
|
||||
Upp;]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 CONSOLE`_APP`_MAIN]&]
|
||||
[s0;l320; [C+75 `{]&]
|
||||
[s0;l320; [C+75 Sqlite3Session sqlite3;]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 if][C+75 (][C@(0.0.255)+75 !][C+75 sqlite3][C@(0.0.255)+75 .
|
||||
][C+75 Open(ConfigFile(][C@3+75 `"simple.db`"][C+75 ))) `{]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"Can`'t
|
||||
create or open database file][C@(0.0.255)+75 `\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 ][*_C@(128.0.255)+75 return][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s0;l320; [C+75 ]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #ifdef][C+75 `_DEBUG]&]
|
||||
[s0;l320; [C+75 sqlite3][C@(0.0.255)+75 .][C+75 SetTrace();]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #endif]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 SQL ][C@(0.0.255)+75 `=][C+75 sqlite3;]&]
|
||||
[s0;l320; [C+75 ]&]
|
||||
[s0;l320; [C+75 SQL][C@(0.0.255)+75 .][C+75 Execute(][C@3+75 `"drop table
|
||||
TEST`"][C+75 );]&]
|
||||
[s0;l320; [C+75 SQL][C@(0.0.255)+75 .][C+75 ClearError();]&]
|
||||
[s0;l320; [C+75 SQL][C@(0.0.255)+75 .][C+75 Execute(][C@3+75 `"create
|
||||
table TEST (A INTEGER, B TEXT)`"][C+75 );]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 ][*_C+75 SqlId][C+75 A(][C@3+75 `"A`"][C+75 ), B(][C@3+75 `"B`"][C+75 ),
|
||||
TEST(][C@3+75 `"TEST`"][C+75 );]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 for][C+75 (][*C@(0.0.255)+75 int][C+75
|
||||
i ][C@(0.0.255)+75 `=][C+75 ][C@3+75 0][C+75 ; i ][C@(0.0.255)+75 <][C+75
|
||||
][C@3+75 10][C+75 ; i][C@(0.0.255)+75 `+`+][C+75 )]&]
|
||||
[s0;l320; [C+75 SQL ][*_C@(0.0.255)+75 `*][*_C+75 Insert(TEST)(A,
|
||||
i)(B, AsString(][*_C@3+75 3][*_C+75 ][*_C@(0.0.255)+75 `*][*_C+75 i))][C+75 ;]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 Sql sql;]&]
|
||||
[s0;l320; [C+75 sql ][*_C@(0.0.255)+75 `*][*_C+75 Select(A, B)][*_C@(0.0.255)+75 .][*_C+75 F
|
||||
rom(TEST)][C+75 ;]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 while][C+75 (sql][C@(0.0.255)+75 .][C+75 Fetch())]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 ][*_C+75 sql][*_C@(0.0.255)+75 `[][*_C+75 A
|
||||
][*_C@(0.0.255)+75 `]][C+75 ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `" ][C@(0.0.255)+75 `\`'][C@3+75 `"
|
||||
][C+75 ][C@(0.0.255)+75 <<][C+75 ][*_C+75 sql][*_C@(0.0.255)+75 `[][*_C+75 B][*_C@(0.0.255)+75 `]
|
||||
][C+75 ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"][C@(0.0.255)+75 `\`'`\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s5;l320; &]
|
||||
[s5;%% SqlId identifiers can be also used as parameter of Sql`::operator`[`]
|
||||
to retrieve particular columns of result`-set.&]
|
||||
[s5; &]
|
||||
[s3;:4: 4. Schema file&]
|
||||
[s5; Schema files can be used to describe the database schema. Such
|
||||
schema files can be used to upload the schema to the database,
|
||||
[s5;%% &]
|
||||
[s3;:4:%% 4. Schema file&]
|
||||
[s5;%% Schema files can be used to describe the database schema.
|
||||
Such schema files can be used to upload the schema to the database,
|
||||
to defined SqlId constants and also to work with database records
|
||||
as C`+`+ structures.&]
|
||||
[s5; Following example demonstrates using schema file to create database
|
||||
schema in SQL database server.&]
|
||||
[s5; MyApp.sch:&]
|
||||
[s7; &]
|
||||
[s7; [* TABLE(TEST)]&]
|
||||
[s7; [* -|INT (A)]&]
|
||||
[s7; [* -|STRING (B, 200)]&]
|
||||
[s7; [* END`_TABLE]&]
|
||||
[s7; &]
|
||||
[s5; MyApp.h&]
|
||||
[s7; #ifndef `_MyApp`_h`_&]
|
||||
[s7; #define `_MyApp`_h`_&]
|
||||
[s7; &]
|
||||
[s7; #include <Core/Core.h>&]
|
||||
[s7; #include <plugin/sqlite3/Sqlite3.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; [* #define SCHEMADIALECT <plugin/sqlite3/Sqlite3Schema.h>]&]
|
||||
[s7; [* #define MODEL <Sql04/MyApp.sch>]&]
|
||||
[s7; [* #include `"Sql/sch`_header.h`"]&]
|
||||
[s7; &]
|
||||
[s7; #endif&]
|
||||
[s7;* &]
|
||||
[s5; main.cpp&]
|
||||
[s7; #include `"MyApp.h`"&]
|
||||
[s7; &]
|
||||
[s7; [* #include <Sql/sch`_schema.h>]&]
|
||||
[s7; [* #include <Sql/sch`_source.h>]&]
|
||||
[s7; &]
|
||||
[s7; CONSOLE`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|Sqlite3Session sqlite3;&]
|
||||
[s7; -|if(!sqlite3.Open(ConfigFile(`"simple.db`"))) `{&]
|
||||
[s7; -|-|Cout() << `"Can`'t create or open database file`\n`";&]
|
||||
[s7; -|-|return;&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|&]
|
||||
[s7; #ifdef `_DEBUG&]
|
||||
[s7; -|sqlite3.SetTrace();&]
|
||||
[s7; #endif&]
|
||||
[s7; &]
|
||||
[s7; -|SQL `= sqlite3;&]
|
||||
[s7; &]
|
||||
[s7; [* -|SqlSchema sch(SQLITE3);]&]
|
||||
[s7; [* -|All`_Tables(sch);]&]
|
||||
[s7; [* -|SqlPerformScript(sch.Upgrade());]&]
|
||||
[s7; [* -|SqlPerformScript(sch.Attributes());]&]
|
||||
[s7; [* -|SQL.ClearError();]&]
|
||||
[s7; &]
|
||||
[s7; -|SqlId A(`"A`"), B(`"B`"), TEST(`"TEST`");&]
|
||||
[s7; &]
|
||||
[s7; -|for(int i `= 0; i < 10; i`+`+)&]
|
||||
[s7; -|-|SQL `* Insert(TEST)(A, i)(B, AsString(3 `* i));&]
|
||||
[s7; &]
|
||||
[s7; -|Sql sql;&]
|
||||
[s7; -|sql `* Select(A, B).From(TEST);&]
|
||||
[s7; -|while(sql.Fetch())&]
|
||||
[s7; -|-|Cout() << sql`[A`] << `" `\`'`" << sql`[B`] << `"`\`'`\n`";&]
|
||||
[s7; `}&]
|
||||
[s7;* &]
|
||||
[s5; &]
|
||||
[s3;:5: 5. Using schema file to define SqlId constants&]
|
||||
[s5; As names of columns are present in the database schema, it is
|
||||
natural to recycle them to create SqlId constants.&]
|
||||
[s5; However, due to C`+`+ one definition rule (.sch files are interpreted
|
||||
as C`+`+ sources, using changing set of macros), you have to
|
||||
mark identifiers using underscore:&]
|
||||
[s5; MyApp.sch:&]
|
||||
[s7; [* TABLE`_](TEST)&]
|
||||
[s7; -|[* INT`_] (A)&]
|
||||
[s7; -|[* STRING`_] (B, 200)&]
|
||||
[s7; END`_TABLE&]
|
||||
[s7; &]
|
||||
[s7; TABLE`_(TEST2)&]
|
||||
[s7; -|[* INT] (A)&]
|
||||
[s7; -|[* STRING] (B, 200)&]
|
||||
[s7; END`_TABLE&]
|
||||
[s5; &]
|
||||
[s5; MyApp.h:&]
|
||||
[s7; #ifndef `_MyApp`_h`_&]
|
||||
[s7; #define `_MyApp`_h`_&]
|
||||
[s7; &]
|
||||
[s7; #include <Core/Core.h>&]
|
||||
[s7; #include <plugin/sqlite3/Sqlite3.h>&]
|
||||
[s7; &]
|
||||
[s7; using namespace Upp;&]
|
||||
[s7; &]
|
||||
[s7; #define SCHEMADIALECT <plugin/sqlite3/Sqlite3Schema.h>&]
|
||||
[s7; #define MODEL <Sql05/MyApp.sch>&]
|
||||
[s7; #include `"Sql/sch`_header.h`"&]
|
||||
[s7; &]
|
||||
[s7; #endif&]
|
||||
[s7; &]
|
||||
[s5; main.cpp:&]
|
||||
[s7; #include `"MyApp.h`"&]
|
||||
[s7; &]
|
||||
[s7; #include <Sql/sch`_schema.h>&]
|
||||
[s7; #include <Sql/sch`_source.h>&]
|
||||
[s7; &]
|
||||
[s7; CONSOLE`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|Sqlite3Session sqlite3;&]
|
||||
[s7; -|if(!sqlite3.Open(ConfigFile(`"simple.db`"))) `{&]
|
||||
[s7; -|-|Cout() << `"Can`'t create or open database file`\n`";&]
|
||||
[s7; -|-|return;&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|&]
|
||||
[s7; #ifdef `_DEBUG&]
|
||||
[s7; -|sqlite3.SetTrace();&]
|
||||
[s7; #endif&]
|
||||
[s7; &]
|
||||
[s7; -|SQL `= sqlite3;&]
|
||||
[s7; &]
|
||||
[s7; -|SqlSchema sch(SQLITE3);&]
|
||||
[s7; -|All`_Tables(sch);&]
|
||||
[s7; -|SqlPerformScript(sch.Upgrade());&]
|
||||
[s7; -|SqlPerformScript(sch.Attributes());&]
|
||||
[s7; -|SQL.ClearError();&]
|
||||
[s7; &]
|
||||
[s7; -|for(int i `= 0; i < 10; i`+`+)&]
|
||||
[s7; -|-|SQL `* Insert(TEST)(A, i)(B, AsString(3 `* i));&]
|
||||
[s7; &]
|
||||
[s7; -|Sql sql;&]
|
||||
[s7; -|sql `* Select(A, B).From(TEST);&]
|
||||
[s7; -|while(sql.Fetch())&]
|
||||
[s7; -|-|Cout() << sql`[A`] << `" `\`'`" << sql`[B`] << `"`\`'`\n`";&]
|
||||
[s7; `}&]
|
||||
[s7; &]
|
||||
[s5; &]
|
||||
[s3;:6: 6. Using structures defined by schema files&]
|
||||
[s5; Schema files also define structures that can be used to fetch,
|
||||
[s5;%% Following example demonstrates using schema file to create
|
||||
database schema in SQL database server.&]
|
||||
[s5;%% [/ MyApp.sch:]&]
|
||||
[s5;%% &]
|
||||
[s0;l320; [*C@(0.0.255)+75 TABLE][C+75 (TEST)]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 INT][C+75 (A)]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 STRING][C+75 (B, ][C@3+75 200][C+75 )]&]
|
||||
[s0;l320; [*C@(0.0.255)+75 END][C@(0.0.255)+75 `_][*C@(0.0.255)+75 TABLE]&]
|
||||
[s5;%% &]
|
||||
[s5;%% [/ MyApp.h:]&]
|
||||
[s5;/%% &]
|
||||
[s0;l320; [C@(128.0.255)+75 #ifndef][C+75 `_MyApp`_h`_]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #define][C+75 `_MyApp`_h`_]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 Core][C@(0.0.255)+75 /][C+75 C
|
||||
ore][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 plugin][C@(0.0.255)+75 /][C+75 s
|
||||
qlite3][C@(0.0.255)+75 /][C+75 Sqlite3][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [*C@(0.0.255)+75 using][C+75 ][*C@(0.0.255)+75 namespace][C+75
|
||||
Upp;]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [*_C@(128.0.255)+75 #define][*_C+75 SCHEMADIALECT ][*_C@(0.0.255)+75 <][*_C+75 plu
|
||||
gin][*_C@(0.0.255)+75 /][*_C+75 sqlite3][*_C@(0.0.255)+75 /][*_C+75 Sqlite3Schema][*_C@(0.0.255)+75 .
|
||||
][*_C+75 h][*_C@(0.0.255)+75 >]&]
|
||||
[s0;l320; [*_C@(128.0.255)+75 #define][*_C+75 MODEL ][*_C@(0.0.255)+75 <][*_C+75 Sql04][*_C@(0.0.255)+75 /
|
||||
][*_C+75 MyApp][*_C@(0.0.255)+75 .][*_C+75 sch][*_C@(0.0.255)+75 >]&]
|
||||
[s0;l320; [*_C@(128.0.255)+75 #include][*_C+75 ][*_C@3+75 `"Sql/sch`_header.h`"]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C@(128.0.255)+75 #endif]&]
|
||||
[s5;%% &]
|
||||
[s5;%% [/ main.cpp:]&]
|
||||
[s5;/%% &]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@3+75 `"MyApp.h`"]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [*_C@(128.0.255)+75 #include][*_C+75 ][*_C@(0.0.255)+75 <][*_C+75 Sql][*_C@(0.0.255)+75 /
|
||||
][*_C+75 sch`_schema][*_C@(0.0.255)+75 .][*_C+75 h][*_C@(0.0.255)+75 >]&]
|
||||
[s0;l320; [*_C@(128.0.255)+75 #include][*_C+75 ][*_C@(0.0.255)+75 <][*_C+75 Sql][*_C@(0.0.255)+75 /
|
||||
][*_C+75 sch`_source][*_C@(0.0.255)+75 .][*_C+75 h][*_C@(0.0.255)+75 >]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 CONSOLE`_APP`_MAIN]&]
|
||||
[s0;l320; [C+75 `{]&]
|
||||
[s0;l320; [C+75 Sqlite3Session sqlite3;]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 if][C+75 (][C@(0.0.255)+75 !][C+75 sqlite3][C@(0.0.255)+75 .
|
||||
][C+75 Open(ConfigFile(][C@3+75 `"simple.db`"][C+75 ))) `{]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"Can`'t
|
||||
create or open database file][C@(0.0.255)+75 `\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 ][*_C@(128.0.255)+75 return][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s0;l320; [C+75 ]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #ifdef][C+75 `_DEBUG]&]
|
||||
[s0;l320; [C+75 sqlite3][C@(0.0.255)+75 .][C+75 SetTrace();]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #endif]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 SQL ][C@(0.0.255)+75 `=][C+75 sqlite3;]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 ][*_C+75 SqlSchema sch(SQLITE3);]&]
|
||||
[s0;l320; [C+75 ][*_C+75 All`_Tables(sch);]&]
|
||||
[s0;l320; [C+75 ][*_C+75 SqlPerformScript(sch][*_C@(0.0.255)+75 .][*_C+75 Upgrade());]&]
|
||||
[s0;l320; [C+75 ][*_C+75 SqlPerformScript(sch][*_C@(0.0.255)+75 .][*_C+75 Attributes());]&]
|
||||
[s0;l320; [C+75 ][*_C+75 SQL][*_C@(0.0.255)+75 .][*_C+75 ClearError();]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 SqlId A(][C@3+75 `"A`"][C+75 ), B(][C@3+75 `"B`"][C+75 ),
|
||||
TEST(][C@3+75 `"TEST`"][C+75 );]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 for][C+75 (][*C@(0.0.255)+75 int][C+75
|
||||
i ][C@(0.0.255)+75 `=][C+75 ][C@3+75 0][C+75 ; i ][C@(0.0.255)+75 <][C+75
|
||||
][C@3+75 10][C+75 ; i][C@(0.0.255)+75 `+`+][C+75 )]&]
|
||||
[s0;l320; [C+75 SQL ][C@(0.0.255)+75 `*][C+75 Insert(TEST)(A,
|
||||
i)(B, AsString(][C@3+75 3][C+75 ][C@(0.0.255)+75 `*][C+75 i));]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 Sql sql;]&]
|
||||
[s0;l320; [C+75 sql ][C@(0.0.255)+75 `*][C+75 Select(A, B)][C@(0.0.255)+75 .][C+75 From(TE
|
||||
ST);]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 while][C+75 (sql][C@(0.0.255)+75 .][C+75 Fetch())]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 sql][C@(0.0.255)+75 `[][C+75 A][C@(0.0.255)+75 `]
|
||||
][C+75 ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `" ][C@(0.0.255)+75 `\`'][C@3+75 `"][C+75
|
||||
][C@(0.0.255)+75 <<][C+75 sql][C@(0.0.255)+75 `[][C+75 B][C@(0.0.255)+75 `]][C+75
|
||||
][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"][C@(0.0.255)+75 `\`'`\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s5;%% &]
|
||||
[s3;:5:%% 5. Using schema file to define SqlId constants&]
|
||||
[s5;%% As names of columns are present in the database schema, it
|
||||
is natural to recycle them to create SqlId constants.&]
|
||||
[s5;%% However, due to C`+`+ one definition rule (.sch files are
|
||||
interpreted as C`+`+ sources, using changing set of macros),
|
||||
you have to mark identifiers using underscore:&]
|
||||
[s5;%% [/ MyApp.sch:]&]
|
||||
[s5;/%% &]
|
||||
[s0;l320; [*C@(0.0.255)+75 TABLE][C@(0.0.255)+75 `_][C+75 (TEST)]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 INT][C@(0.0.255)+75 `_][C+75
|
||||
(A)]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 STRING][C@(0.0.255)+75 `_][C+75
|
||||
(B, ][C@3+75 200][C+75 )]&]
|
||||
[s0;l320; [*C@(0.0.255)+75 END][C@(0.0.255)+75 `_][*C@(0.0.255)+75 TABLE]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [*C@(0.0.255)+75 TABLE][C@(0.0.255)+75 `_][C+75 (TEST2)]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 INT][C+75 (A)]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 STRING][C+75 (B, ][C@3+75 200][C+75 )]&]
|
||||
[s0;l320; [*C@(0.0.255)+75 END][C@(0.0.255)+75 `_][*C@(0.0.255)+75 TABLE]&]
|
||||
[s5;%% &]
|
||||
[s5;%% MyApp.h:&]
|
||||
[s5;%% &]
|
||||
[s0;l320; [C@(128.0.255)+75 #ifndef][C+75 `_MyApp`_h`_]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #define][C+75 `_MyApp`_h`_]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 Core][C@(0.0.255)+75 /][C+75 C
|
||||
ore][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 plugin][C@(0.0.255)+75 /][C+75 s
|
||||
qlite3][C@(0.0.255)+75 /][C+75 Sqlite3][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [*C@(0.0.255)+75 using][C+75 ][*C@(0.0.255)+75 namespace][C+75
|
||||
Upp;]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C@(128.0.255)+75 #define][C+75 SCHEMADIALECT ][C@(0.0.255)+75 <][C+75 plugin][C@(0.0.255)+75 /
|
||||
][C+75 sqlite3][C@(0.0.255)+75 /][C+75 Sqlite3Schema][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >
|
||||
]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #define][C+75 MODEL ][C@(0.0.255)+75 <][C+75 Sql05][C@(0.0.255)+75 /
|
||||
][C+75 MyApp][C@(0.0.255)+75 .][C+75 sch][C@(0.0.255)+75 >]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@3+75 `"Sql/sch`_header.h`"]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C@(128.0.255)+75 #endif]&]
|
||||
[s5;%% &]
|
||||
[s5;%% main.cpp:&]
|
||||
[s5;%% &]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@3+75 `"MyApp.h`"]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 Sql][C@(0.0.255)+75 /][C+75 s
|
||||
ch`_schema][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 Sql][C@(0.0.255)+75 /][C+75 s
|
||||
ch`_source][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 CONSOLE`_APP`_MAIN]&]
|
||||
[s0;l320; [C+75 `{]&]
|
||||
[s0;l320; [C+75 Sqlite3Session sqlite3;]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 if][C+75 (][C@(0.0.255)+75 !][C+75 sqlite3][C@(0.0.255)+75 .
|
||||
][C+75 Open(ConfigFile(][C@3+75 `"simple.db`"][C+75 ))) `{]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"Can`'t
|
||||
create or open database file][C@(0.0.255)+75 `\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 ][*_C@(128.0.255)+75 return][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s0;l320; [C+75 ]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #ifdef][C+75 `_DEBUG]&]
|
||||
[s0;l320; [C+75 sqlite3][C@(0.0.255)+75 .][C+75 SetTrace();]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #endif]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 SQL ][C@(0.0.255)+75 `=][C+75 sqlite3;]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 SqlSchema sch(SQLITE3);]&]
|
||||
[s0;l320; [C+75 All`_Tables(sch);]&]
|
||||
[s0;l320; [C+75 SqlPerformScript(sch][C@(0.0.255)+75 .][C+75 Upgrade());]&]
|
||||
[s0;l320; [C+75 SqlPerformScript(sch][C@(0.0.255)+75 .][C+75 Attributes());]&]
|
||||
[s0;l320; [C+75 SQL][C@(0.0.255)+75 .][C+75 ClearError();]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 for][C+75 (][*C@(0.0.255)+75 int][C+75
|
||||
i ][C@(0.0.255)+75 `=][C+75 ][C@3+75 0][C+75 ; i ][C@(0.0.255)+75 <][C+75
|
||||
][C@3+75 10][C+75 ; i][C@(0.0.255)+75 `+`+][C+75 )]&]
|
||||
[s0;l320; [C+75 SQL ][C@(0.0.255)+75 `*][C+75 Insert(TEST)(A,
|
||||
i)(B, AsString(][C@3+75 3][C+75 ][C@(0.0.255)+75 `*][C+75 i));]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 Sql sql;]&]
|
||||
[s0;l320; [C+75 sql ][C@(0.0.255)+75 `*][C+75 Select(A, B)][C@(0.0.255)+75 .][C+75 From(TE
|
||||
ST);]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 while][C+75 (sql][C@(0.0.255)+75 .][C+75 Fetch())]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 sql][C@(0.0.255)+75 `[][C+75 A][C@(0.0.255)+75 `]
|
||||
][C+75 ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `" ][C@(0.0.255)+75 `\`'][C@3+75 `"][C+75
|
||||
][C@(0.0.255)+75 <<][C+75 sql][C@(0.0.255)+75 `[][C+75 B][C@(0.0.255)+75 `]][C+75
|
||||
][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"][C@(0.0.255)+75 `\`'`\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s5;%% &]
|
||||
[s3;:6:%% 6. Using structures defined by schema files&]
|
||||
[s5;%% Schema files also define structures that can be used to fetch,
|
||||
insert or update database records. Names of such structures are
|
||||
identical to the names of tables, with [* S`_] prefix:&]
|
||||
[s7; #include `"MyApp.h`"&]
|
||||
[s7; &]
|
||||
[s7; #include <Sql/sch`_schema.h>&]
|
||||
[s7; #include <Sql/sch`_source.h>&]
|
||||
[s7; &]
|
||||
[s7; CONSOLE`_APP`_MAIN&]
|
||||
[s7; `{&]
|
||||
[s7; -|Sqlite3Session sqlite3;&]
|
||||
[s7; -|if(!sqlite3.Open(ConfigFile(`"simple.db`"))) `{&]
|
||||
[s7; -|-|Cout() << `"Can`'t create or open database file`\n`";&]
|
||||
[s7; -|-|return;&]
|
||||
[s7; -|`}&]
|
||||
[s7; -|&]
|
||||
[s7; #ifdef `_DEBUG&]
|
||||
[s7; -|sqlite3.SetTrace();&]
|
||||
[s7; #endif&]
|
||||
[s7; &]
|
||||
[s7; -|SQL `= sqlite3;&]
|
||||
[s7; &]
|
||||
[s7; -|SqlSchema sch(SQLITE3);&]
|
||||
[s7; -|All`_Tables(sch);&]
|
||||
[s7; -|SqlPerformScript(sch.Upgrade());&]
|
||||
[s7; -|SqlPerformScript(sch.Attributes());&]
|
||||
[s7; -|SQL.ClearError();&]
|
||||
[s7; &]
|
||||
[s7; -|[* S`_TEST] x;&]
|
||||
[s7; -|for(int i `= 0; i < 10; i`+`+) `{&]
|
||||
[s7; -|-|[* x.A `= i;]&]
|
||||
[s7; -|-|[* x.B `= AsString(3 `* i);]&]
|
||||
[s7; -|-|[* SQL `* Insert(x);]&]
|
||||
[s7; -|`}&]
|
||||
[s7; &]
|
||||
[s7; -|Sql sql;&]
|
||||
[s7; -|sql `* Select([* x]).From(TEST);&]
|
||||
[s7; -|while(sql.Fetch([* x]))&]
|
||||
[s7; -|-|Cout() << [* x.A] << `" `\`'`" << [* x.B] << `"`\`'`\n`";&]
|
||||
[s7; `}&]
|
||||
[s5; &]
|
||||
[s3; Recommended tutorials:&]
|
||||
[s5; If you want to learn more, we have several tutorials that you
|
||||
can find useful:&]
|
||||
[s5;l160;i150;O0;~~~0; [^topic`:`/`/Skylark`/srcdoc`/Tutorial`_en`-us^ Skylark]
|
||||
[s5;%% &]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@3+75 `"MyApp.h`"]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 Sql][C@(0.0.255)+75 /][C+75 s
|
||||
ch`_schema][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #include][C+75 ][C@(0.0.255)+75 <][C+75 Sql][C@(0.0.255)+75 /][C+75 s
|
||||
ch`_source][C@(0.0.255)+75 .][C+75 h][C@(0.0.255)+75 >]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 CONSOLE`_APP`_MAIN]&]
|
||||
[s0;l320; [C+75 `{]&]
|
||||
[s0;l320; [C+75 Sqlite3Session sqlite3;]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 if][C+75 (][C@(0.0.255)+75 !][C+75 sqlite3][C@(0.0.255)+75 .
|
||||
][C+75 Open(ConfigFile(][C@3+75 `"simple.db`"][C+75 ))) `{]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"Can`'t
|
||||
create or open database file][C@(0.0.255)+75 `\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 ][*_C@(128.0.255)+75 return][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s0;l320; [C+75 ]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #ifdef][C+75 `_DEBUG]&]
|
||||
[s0;l320; [C+75 sqlite3][C@(0.0.255)+75 .][C+75 SetTrace();]&]
|
||||
[s0;l320; [C@(128.0.255)+75 #endif]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 SQL ][C@(0.0.255)+75 `=][C+75 sqlite3;]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 SqlSchema sch(SQLITE3);]&]
|
||||
[s0;l320; [C+75 All`_Tables(sch);]&]
|
||||
[s0;l320; [C+75 SqlPerformScript(sch][C@(0.0.255)+75 .][C+75 Upgrade());]&]
|
||||
[s0;l320; [C+75 SqlPerformScript(sch][C@(0.0.255)+75 .][C+75 Attributes());]&]
|
||||
[s0;l320; [C+75 SQL][C@(0.0.255)+75 .][C+75 ClearError();]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 ][*_C+75 S`_TEST x;]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 for][C+75 (][*C@(0.0.255)+75 int][C+75
|
||||
i ][C@(0.0.255)+75 `=][C+75 ][C@3+75 0][C+75 ; i ][C@(0.0.255)+75 <][C+75
|
||||
][C@3+75 10][C+75 ; i][C@(0.0.255)+75 `+`+][C+75 ) `{]&]
|
||||
[s0;l320; [C+75 ][*_C+75 x][*_C@(0.0.255)+75 .][*_C+75 A ][*_C@(0.0.255)+75 `=][*_C+75
|
||||
i;]&]
|
||||
[s0;l320; [C+75 ][*_C+75 x][*_C@(0.0.255)+75 .][*_C+75 B ][*_C@(0.0.255)+75 `=][*_C+75
|
||||
AsString(][*_C@3+75 3][*_C+75 ][*_C@(0.0.255)+75 `*][*_C+75 i);]&]
|
||||
[s0;l320; [C+75 ][*_C+75 SQL ][*_C@(0.0.255)+75 `*][*_C+75 Insert(x);]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s0;l320;C+75 &]
|
||||
[s0;l320; [C+75 Sql sql;]&]
|
||||
[s0;l320; [C+75 sql ][C@(0.0.255)+75 `*][C+75 Select(][*_C+75 x][C+75 )][C@(0.0.255)+75 .][C+75 F
|
||||
rom(TEST);]&]
|
||||
[s0;l320; [C+75 ][*C@(0.0.255)+75 while][C+75 (sql][C@(0.0.255)+75 .][C+75 Fetch(][*_C+75 x][C+75 )
|
||||
)]&]
|
||||
[s0;l320; [C+75 Cout() ][C@(0.0.255)+75 <<][C+75 ][*_C+75 x][*_C@(0.0.255)+75 .][*_C+75 A
|
||||
][C+75 ][C@(0.0.255)+75 <<][C+75 ][C@3+75 `" ][C@(0.0.255)+75 `\`'][C@3+75 `"][C+75
|
||||
][C@(0.0.255)+75 <<][C+75 ][*_C+75 x][*_C@(0.0.255)+75 .][*_C+75 B][C+75
|
||||
][C@(0.0.255)+75 <<][C+75 ][C@3+75 `"][C@(0.0.255)+75 `\`'`\n][C@3+75 `"][C+75 ;]&]
|
||||
[s0;l320; [C+75 `}]&]
|
||||
[s5;l320;%% &]
|
||||
[s3;%% Recommended tutorials:&]
|
||||
[s5;%% If you want to learn more, we have several tutorials that
|
||||
you can find useful:&]
|
||||
[s5;l160;i150;O0;~~~0;%% [^topic`:`/`/Skylark`/srcdoc`/Tutorial`_en`-us^ Skylark]
|
||||
`- now you know everything about databases `- why not to use
|
||||
your knowledge to become web development star?&]
|
||||
[s5;l160;i150;O0;~~~0; [^topic`:`/`/Core`/srcdoc`/Tutorial`_en`-us^ U`+`+
|
||||
[s5;l160;i150;O0;~~~0;%% [^topic`:`/`/Core`/srcdoc`/Tutorial`_en`-us^ U`+`+
|
||||
Core value types] `- still not very confident with U`+`+. In
|
||||
this tutorial you will learn basics.]]
|
||||
Loading…
Add table
Add a link
Reference in a new issue