SlideShare a Scribd company logo
1 of 37
Download to read offline
Look Ma,
“update DB to HTML5 using C++”,
no hands!
POCOC++ PORTABLE COMPONENTS
alex@pocoproject.org
2013
Content
> The Problem
> The Solution
> The Anatomy of the Solution
> The Heart and Soul of the Solution
> Let’s Dance - code example
> Performance-conscious options
> A better solution - from DB to HTML, no hands
> Conclusion
"A man will be imprisoned in a room
with a door that's unlocked and opens
inwards; as long as it does not occur to
him to pull rather than push.
Ludwig Wittgenstein
A Brief History of Data Access
Data Formats
> often in proprietary binary format
> transform into character strings of desired format
> server-side needs an equivalent of HTML rendering engine
So,how do we do this?
> generate the desired format in the database :-
> use dynamic language
> mix HTML with server-side code and compile on the fly (shudder)
> browser plugin (double-shudder)
> or ... use static language on the server-side and AJA(X|J) in the browser?
SELECT * FROM Simpsons
> discover column count
The Problem
> discover column data types
> bind returned data to variables
SQLRETURN rc;
SQLHENV henv = SQL_NULL_HENV;
SQLHDBC hdbc = SQL_NULL_HDBC;
SQLHSTMT hstmt = SQL_NULL_HSTMT;
rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
odbc_check_env (rc, henv);
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
odbc_check_env (rc, henv);
rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
odbc_check_dbc (rc, hdbc);
SQLCHAR connectOutput[1024] = {0};
SQLSMALLINT result;
rc = SQLDriverConnect(hdbc,NULL,(SQLCHAR*)dbConnString.c_str(),(SQLSMALLINT)SQL_NTS,connectOutput,sizeof(connectOutput),&result,SQL_DRIVER_NOPROMPT);
odbc_check_dbc (rc, hdbc);
sql = "SELECT * FROM Simpsons";
SQLCHAR* pStr = (SQLCHAR*) sql.c_str();
rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length());
odbc_check_stmt (rc, hstmt);
char name[50] = { 0 };
SQLLEN lengths[3] = { 0 };
int age = 0;
float weight = 0.0f;
std::memset(&sixth, 0, sizeof(sixth));
rc = SQLBindCol(hstmt, (SQLUSMALLINT) 1, SQL_C_CHAR, (SQLPOINTER) chr, (SQLINTEGER) sizeof(chr[0]), &lengths[0]);
odbc_check_stmt (rc, hstmt);
rc = SQLBindCol(hstmt, (SQLUSMALLINT) 2, SQL_C_INTEGER, (SQLPOINTER) &age, (SQLINTEGER) sizeof(age), &lengths[1]);
odbc_check_stmt (rc, hstmt);
rc = SQLBindCol(hstmt, (SQLUSMALLINT) 3, SQL_C_BINARY, (SQLPOINTER) &weight, (SQLINTEGER) sizeof(weight), &lengths[2]);
odbc_check_stmt (rc, hstmt);
printf(“Name: %s, Age: %d, Weight: %f”, name, age, weight);
! !
“solution”
© mark du toit
using namespace Poco::Data::SQLite;
int main()
{
Session session("SQLite", "simpsons.db");
std::cout << RecordSet(session,
"SELECT * FROM Simpsons");
return 0;
}
The Solution
© mark du toit
Statement stmt =
(session << "SELECT * FROM Simpsons", now);
RecordSet rs(stmt);
ostream& operator << (ostream &os,
const RecordSet& rs)
{
return rs.copy(os);
}
The Anatomy of the Solution
(step - by - step)
The Anatomy of the Solution
(under the hood)
using namespace std;
ostream& RecordSet::copy(ostream& os, size_t offset = 0, size_t length = END)
{
RowFormatter& rf = (*_pBegin)->getFormatter();
os << rf.prefix();
copyNames(os);
copyValues(os, offset, length);
os << rf.postfix();
return os;
}
ostream& RecordSet::copyValues(ostream& os, size_t offset, size_t length)
{
RowIterator begin = *_pBegin + offset;
RowIterator end = (RowIterator::END != length) ? it + length : *_pEnd;
std::copy(begin, end, std::ostream_iterator<Row>(os));
return os;
}
Row& RowIterator::operator * ()
{
if (END == _position)
throw InvalidAccessException("End of iterator reached.");
return _pRecordSet->row(_position);
}
ostream& operator << (ostream &os, const Row& row)
{
os << row.valuesToString();
return os;
}
const string& Row::valuesToString() const
{
return _pFormatter->formatValues(values(), _valueStr);
}
The Anatomy of the Solution,contd.
(STL - compliance)
class Row
{
public:
// ...
template <typename T>
void set(size_t pos, const T& val)
{
try { _values.at(pos) = val; }
catch (out_of_range&)
{ throw RangeException("Invalid column."); }
}
// ...
private:
vector<Poco::Dynamic::Var> _values;
};
The Heart of the Solution
(Row::set)
namespace Poco {
namespace Dynamic {
class Var
{
public:
// ...
template <typename T>
Var(const T& val):
_pHolder(new VarHolderImpl<T>(val))
{
}
// ...
private:
VarHolder* _pHolder;
};
} } // namespace Poco::Dynamic
The Soul of the Machine
(Poco::Dynamic::Var)
* Design based on boost::any
So,where was boost::any found lacking ?
It’s a great idea with limited applicability -
dynamic on receiving,but static on the giving end.
using boost::any;
using boost::any_cast;
typedef std::list<any> many;
int ival = 42;
std::string sval = “fourty two”;
values.push_back(ival);
values.push_back(sval);
std::string sival = values[0]; // oops!, compile error
sival = any_cast<std::string>(values[0]); // still oops!, throw
Var in Practical Use
std::string s1("string");
Poco::Int8 s2(23);
std::vector<Var> s16;
s16.push_back(s1);
s16.push_back(s2);
Var a1(s16);
std::string res = a1.convert<std::string>();
// ["string", 23]
DynamicStruct aStruct;
aStruct["First Name"] = "Junior";
aStruct["Last Name"] = "POCO";
aStruct["Age"] = 1;
Var a1(aStruct);
std::string res = a1.convert<std::string>();
// { "Age”: 1, "First Name": "Junior", "Last Name" : "POCO" }
std::string str("42");
Var v1 = str; // "42"
double d = v1; // 42.0
Var v2 = d + 1.0; // 43.0
float f = v2 + 1; // 44.0
What Else is in the Var Box
> Dynamic array, pair and struct (map) support
(Poco::Dynamic::Pair/Struct)
> JSON (de)serialization of the above
> Empty value support (very handy with null DB fields)
> Strict conversion checks
namespace Poco {
namespace Dynamic {
class VarHolder
{
public:
virtual ~VarHolder();
virtual void convert(int& val) const;
// ...
protected:
VarHolder();
// ...
};
template <typename T> // for end-user extensions
class VarHolderImpl: public VarHolder
{
//...
};
template <> // native and frequently used types specializations provided by POCO
class VarHolderImpl<int>: public VarHolder
{
//...
};
//...
}}
The Soul of the Machine
(Poco::Dynamic::VarHolder)
Poco::Net::HTTPServer
The Machine Assembled
RecordSetStatement
RowFormatter
Session
Poco::Dynamic::Var
Let’s Dance
class DataRequestHandler: public HTTPRequestHandler
{
public:
void handleRequest(HTTPServerRequest& request,
HTTPServerResponse& response)
{
response.setChunkedTransferEncoding(true);
response.setContentType("text/xml");
ostream& ostr = response.send();
Session sess("SQLite", "sample.db");
ostr << RecordSet(sess,
"SELECT * FROM Simpsons",
XMLFormatter());
}
};
A Real World Example
Is it REALLY Dynamic?
In a sense,yes - values are instantiated at runtime.
But they’re strongly typed and bound early.
Dig deep enough and there is no such thing as
dynamic.
struct Person
{
std::string name;
std::string address;
int age;
};
But what if I need performance?
There is,of course,a lean and elegant static workaround.
In fact,several of them ...
namespace Poco {
namespace Data {
template <>
class TypeHandler<Person>
{
public:
static std::size_t size()
{
return 3;
}
static void bind(size_t pos, const Person& person, AbstractBinder::Ptr pBinder, Direction dir)
{
TypeHandler<std::string>::bind(pos++, person.name, pBinder, dir);
TypeHandler<std::string>::bind(pos++, person.address, pBinder, dir);
TypeHandler<int>::bind(pos++, person.age, pBinder, dir);
}
static void extract(size_t pos, Person& person, const Person& deflt, AbstractExtractor::Ptr p)
{
TypeHandler<std::string>::extract(pos++, person.name, deflt.name, p);
TypeHandler<std::string>::extract(pos++, person.address, deflt.address, p);
TypeHandler<int>::extract(pos++, person.age, deflt.age, p);
}
};
} }
Scaffolding - wrap Person into a TypeHandler
Person person =
{
"Bart Simpson",
"Springfield",
12
};
session << "INSERT INTO Person VALUES(?, ?, ?)", use(person);
std::vector<Person> people;
session << "SELECT Name, Address, Age FROM Person",into(people), now;
And Life is Good Again
std::string name, address;
int age;
session << "INSERT INTO Person VALUES(?, ?, ?)",
use(name),
use(address),
use(age);
using namespace std;
using namespace Poco;
typedef Tuple<string, string, int> Person;
typedef vector<Person> People;
People people;
people.push_back(Person("Bart Simpson", "Springfield", 12));
people.push_back(Person("Lisa Simpson", "Springfield", 10));
session << "INSERT INTO Person VALUES(?, ?, ?)", use(people), now;
people.clear();
session << "SELECT Name, Address, Age FROM Person", into(people), now;
But wait,there’s more!
Nothing but pulling so far :-(
Push,or my money back !
SELECT * FROM Simpsons
Poco::Net::HTTPServer
When Push comes to Shove ...
RecordSet
WebSocket RowFormatter Callback
Poco::Dynamic::Var
Event
RegisterConnect
Data
Statement
DBEventHandler():_session("SQLite", "sample.db"),
_notifier(_session)
{
_notifier.insert += delegate(this, &DBEventHandler::onInsert);
_notifier.update += delegate(this, &DBEventHandler::onUpdate);
}
void DBEventHandler::onInsert(const void* pSender)
{
Notifier* pN = notifier(pSender);
Poco::Int64 rowID = pN->getRow();
std::cout << "Inserted row " << rowID << std::endl;
notify(rowID);
}
Under the Hood - DB Events
void DBEventHandler::notify(Poco::Int64 rowID)
{
std::ostringstream os;
CSVFormatter cf;
Statement stmt =
(_session << "SELECT rowid, Name, Address, Age
FROM Person
WHERE rowid = ?",
use(rowID),
format(cf),
now);
os << RecordSet(stmt);
_factory.handler().send(os.str());
}
Under the Hood - DB Event Notification
try
{
if (!_pWS)
_pWS = new WebSocket(request, response);
std::cout << "WebSocket connection established.";
char buffer[1024];
int n;
do
{
n = _pWS->receiveFrame(buffer, sizeof(buffer), _flags);
}
while (n > 0 || (_flags & WebSocket::FRAME_OP_BITMASK) !=
WebSocket::FRAME_OP_CLOSE);
std::cout << "WebSocket connection closed." << std::endl;
}
catch (WebSocketException& exc)
{ /* ... */ }
Under the Hood - WebSocket Loop
class WebSocketRequestHandler
{
// ...
void send(const std::string& buffer)
{
_pWS->sendFrame(buffer.data(),
buffer.size(),
_flags);
}
// ...
};
Under the Hood - WebSocket Send
function WebSocketOpen() {
if ("WebSocket" in window) {
ws = new WebSocket("ws://localhost:9980/ws");
ws.onopen = function() {
ws.send("Hello, world!");
};
ws.onmessage = function(evt) {
var arr = evt.data.split(",");
if (arr.length >= 4) {
updateTable(arr[0], arr[1], arr[2], arr[3]);
}
}
};
Under the Hood - WebSocket,the browser end
A Real Virtual World Example
ACCU Overload Journal Articles
http://accu.org/index.php/journals/1511
http://accu.org/index.php/journals/1502
Upcoming:“Dynamic C++” (June ACCU Overload)
Last but not Least
POCO
> large, comprehensive, well-designed framework
> designed for practical everyday use, with end-user in mind
> makes C++ programming fun
> 100% standard C++
> not reinventing the wheel (except when necessary ;-)
https://github.com/pocoproject
http://pocoproject.org
got POCO?C++ PORTABLE COMPONENTS
http://pocoproject.org alex@pocoproject.org

More Related Content

What's hot

Concurrency Concepts in Java
Concurrency Concepts in JavaConcurrency Concepts in Java
Concurrency Concepts in JavaDoug Hawkins
 
The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88Mahmoud Samir Fayed
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Sergey Platonov
 
The Rust Programming Language: an Overview
The Rust Programming Language: an OverviewThe Rust Programming Language: an Overview
The Rust Programming Language: an OverviewRoberto Casadei
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsAzul Systems, Inc.
 
Coscup2021-rust-toturial
Coscup2021-rust-toturialCoscup2021-rust-toturial
Coscup2021-rust-toturialWayne Tsai
 
(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your GroovyAlonso Torres
 
Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CSteffen Wenz
 
Coscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usageCoscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usageWayne Tsai
 
Powered by Python - PyCon Germany 2016
Powered by Python - PyCon Germany 2016Powered by Python - PyCon Germany 2016
Powered by Python - PyCon Germany 2016Steffen Wenz
 
The Ring programming language version 1.2 book - Part 79 of 84
The Ring programming language version 1.2 book - Part 79 of 84The Ring programming language version 1.2 book - Part 79 of 84
The Ring programming language version 1.2 book - Part 79 of 84Mahmoud Samir Fayed
 
LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기Wanbok Choi
 

What's hot (20)

Rust ⇋ JavaScript
Rust ⇋ JavaScriptRust ⇋ JavaScript
Rust ⇋ JavaScript
 
Concurrency Concepts in Java
Concurrency Concepts in JavaConcurrency Concepts in Java
Concurrency Concepts in Java
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 
The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88The Ring programming language version 1.3 book - Part 84 of 88
The Ring programming language version 1.3 book - Part 84 of 88
 
Groovy
GroovyGroovy
Groovy
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
 
The Rust Programming Language: an Overview
The Rust Programming Language: an OverviewThe Rust Programming Language: an Overview
The Rust Programming Language: an Overview
 
Why rust?
Why rust?Why rust?
Why rust?
 
Python GC
Python GCPython GC
Python GC
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
Blazing Fast Windows 8 Apps using Visual C++
Blazing Fast Windows 8 Apps using Visual C++Blazing Fast Windows 8 Apps using Visual C++
Blazing Fast Windows 8 Apps using Visual C++
 
Coscup2021-rust-toturial
Coscup2021-rust-toturialCoscup2021-rust-toturial
Coscup2021-rust-toturial
 
Why Sifu
Why SifuWhy Sifu
Why Sifu
 
(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy(Greach 2015) Dsl'ing your Groovy
(Greach 2015) Dsl'ing your Groovy
 
Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in C
 
Coscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usageCoscup2021 - useful abstractions at rust and it's practical usage
Coscup2021 - useful abstractions at rust and it's practical usage
 
Powered by Python - PyCon Germany 2016
Powered by Python - PyCon Germany 2016Powered by Python - PyCon Germany 2016
Powered by Python - PyCon Germany 2016
 
The Ring programming language version 1.2 book - Part 79 of 84
The Ring programming language version 1.2 book - Part 79 of 84The Ring programming language version 1.2 book - Part 79 of 84
The Ring programming language version 1.2 book - Part 79 of 84
 
LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기
 

Similar to Look Ma, “update DB to HTML5 using C++”, no hands! 

C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerAndrey Karpov
 
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloadingkinan keshkeh
 
Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2VMware Tanzu
 
Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Platonov Sergey
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Alexander Granin
 
A scrupulous code review - 15 bugs in C++ code
A scrupulous code review - 15 bugs in C++ codeA scrupulous code review - 15 bugs in C++ code
A scrupulous code review - 15 bugs in C++ codePVS-Studio LLC
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Juan Pablo
 
Java script
 Java script Java script
Java scriptbosybosy
 
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdf
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdfDoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdf
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdfaathiauto
 
How to Write Node.js Module
How to Write Node.js ModuleHow to Write Node.js Module
How to Write Node.js ModuleFred Chien
 
Some examples of the 64-bit code errors
Some examples of the 64-bit code errorsSome examples of the 64-bit code errors
Some examples of the 64-bit code errorsPVS-Studio
 
C++ Programming - 1st Study
C++ Programming - 1st StudyC++ Programming - 1st Study
C++ Programming - 1st StudyChris Ohk
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereАлексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereSergey Platonov
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaJevgeni Kabanov
 

Similar to Look Ma, “update DB to HTML5 using C++”, no hands!  (20)

C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
 
Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2Leap Ahead with Redis 6.2
Leap Ahead with Redis 6.2
 
Bind me if you can
Bind me if you canBind me if you can
Bind me if you can
 
Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++
 
A scrupulous code review - 15 bugs in C++ code
A scrupulous code review - 15 bugs in C++ codeA scrupulous code review - 15 bugs in C++ code
A scrupulous code review - 15 bugs in C++ code
 
Modern C++
Modern C++Modern C++
Modern C++
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
Java script
 Java script Java script
Java script
 
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdf
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdfDoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdf
DoublyList-cpp- #include -DoublyList-h- using namespace std- void Doub.pdf
 
How to Write Node.js Module
How to Write Node.js ModuleHow to Write Node.js Module
How to Write Node.js Module
 
Some examples of the 64-bit code errors
Some examples of the 64-bit code errorsSome examples of the 64-bit code errors
Some examples of the 64-bit code errors
 
C++ Programming - 1st Study
C++ Programming - 1st StudyC++ Programming - 1st Study
C++ Programming - 1st Study
 
C to perl binding
C to perl bindingC to perl binding
C to perl binding
 
Effective Object Oriented Design in Cpp
Effective Object Oriented Design in CppEffective Object Oriented Design in Cpp
Effective Object Oriented Design in Cpp
 
greenDAO
greenDAOgreenDAO
greenDAO
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereАлексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhere
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for Java
 

Recently uploaded

SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

Look Ma, “update DB to HTML5 using C++”, no hands! 

  • 1. Look Ma, “update DB to HTML5 using C++”, no hands! POCOC++ PORTABLE COMPONENTS alex@pocoproject.org 2013
  • 2. Content > The Problem > The Solution > The Anatomy of the Solution > The Heart and Soul of the Solution > Let’s Dance - code example > Performance-conscious options > A better solution - from DB to HTML, no hands > Conclusion
  • 3. "A man will be imprisoned in a room with a door that's unlocked and opens inwards; as long as it does not occur to him to pull rather than push. Ludwig Wittgenstein
  • 4. A Brief History of Data Access
  • 5. Data Formats > often in proprietary binary format > transform into character strings of desired format > server-side needs an equivalent of HTML rendering engine
  • 6. So,how do we do this? > generate the desired format in the database :- > use dynamic language > mix HTML with server-side code and compile on the fly (shudder) > browser plugin (double-shudder) > or ... use static language on the server-side and AJA(X|J) in the browser?
  • 7. SELECT * FROM Simpsons > discover column count The Problem > discover column data types > bind returned data to variables
  • 8. SQLRETURN rc; SQLHENV henv = SQL_NULL_HENV; SQLHDBC hdbc = SQL_NULL_HDBC; SQLHSTMT hstmt = SQL_NULL_HSTMT; rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); odbc_check_env (rc, henv); rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0); odbc_check_env (rc, henv); rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); odbc_check_dbc (rc, hdbc); SQLCHAR connectOutput[1024] = {0}; SQLSMALLINT result; rc = SQLDriverConnect(hdbc,NULL,(SQLCHAR*)dbConnString.c_str(),(SQLSMALLINT)SQL_NTS,connectOutput,sizeof(connectOutput),&result,SQL_DRIVER_NOPROMPT); odbc_check_dbc (rc, hdbc); sql = "SELECT * FROM Simpsons"; SQLCHAR* pStr = (SQLCHAR*) sql.c_str(); rc = SQLPrepare(hstmt, pStr, (SQLINTEGER) sql.length()); odbc_check_stmt (rc, hstmt); char name[50] = { 0 }; SQLLEN lengths[3] = { 0 }; int age = 0; float weight = 0.0f; std::memset(&sixth, 0, sizeof(sixth)); rc = SQLBindCol(hstmt, (SQLUSMALLINT) 1, SQL_C_CHAR, (SQLPOINTER) chr, (SQLINTEGER) sizeof(chr[0]), &lengths[0]); odbc_check_stmt (rc, hstmt); rc = SQLBindCol(hstmt, (SQLUSMALLINT) 2, SQL_C_INTEGER, (SQLPOINTER) &age, (SQLINTEGER) sizeof(age), &lengths[1]); odbc_check_stmt (rc, hstmt); rc = SQLBindCol(hstmt, (SQLUSMALLINT) 3, SQL_C_BINARY, (SQLPOINTER) &weight, (SQLINTEGER) sizeof(weight), &lengths[2]); odbc_check_stmt (rc, hstmt); printf(“Name: %s, Age: %d, Weight: %f”, name, age, weight); ! ! “solution” © mark du toit
  • 9. using namespace Poco::Data::SQLite; int main() { Session session("SQLite", "simpsons.db"); std::cout << RecordSet(session, "SELECT * FROM Simpsons"); return 0; } The Solution © mark du toit
  • 10. Statement stmt = (session << "SELECT * FROM Simpsons", now); RecordSet rs(stmt); ostream& operator << (ostream &os, const RecordSet& rs) { return rs.copy(os); } The Anatomy of the Solution (step - by - step)
  • 11. The Anatomy of the Solution (under the hood) using namespace std; ostream& RecordSet::copy(ostream& os, size_t offset = 0, size_t length = END) { RowFormatter& rf = (*_pBegin)->getFormatter(); os << rf.prefix(); copyNames(os); copyValues(os, offset, length); os << rf.postfix(); return os; } ostream& RecordSet::copyValues(ostream& os, size_t offset, size_t length) { RowIterator begin = *_pBegin + offset; RowIterator end = (RowIterator::END != length) ? it + length : *_pEnd; std::copy(begin, end, std::ostream_iterator<Row>(os)); return os; }
  • 12. Row& RowIterator::operator * () { if (END == _position) throw InvalidAccessException("End of iterator reached."); return _pRecordSet->row(_position); } ostream& operator << (ostream &os, const Row& row) { os << row.valuesToString(); return os; } const string& Row::valuesToString() const { return _pFormatter->formatValues(values(), _valueStr); } The Anatomy of the Solution,contd. (STL - compliance)
  • 13. class Row { public: // ... template <typename T> void set(size_t pos, const T& val) { try { _values.at(pos) = val; } catch (out_of_range&) { throw RangeException("Invalid column."); } } // ... private: vector<Poco::Dynamic::Var> _values; }; The Heart of the Solution (Row::set)
  • 14. namespace Poco { namespace Dynamic { class Var { public: // ... template <typename T> Var(const T& val): _pHolder(new VarHolderImpl<T>(val)) { } // ... private: VarHolder* _pHolder; }; } } // namespace Poco::Dynamic The Soul of the Machine (Poco::Dynamic::Var) * Design based on boost::any
  • 15. So,where was boost::any found lacking ? It’s a great idea with limited applicability - dynamic on receiving,but static on the giving end. using boost::any; using boost::any_cast; typedef std::list<any> many; int ival = 42; std::string sval = “fourty two”; values.push_back(ival); values.push_back(sval); std::string sival = values[0]; // oops!, compile error sival = any_cast<std::string>(values[0]); // still oops!, throw
  • 16. Var in Practical Use std::string s1("string"); Poco::Int8 s2(23); std::vector<Var> s16; s16.push_back(s1); s16.push_back(s2); Var a1(s16); std::string res = a1.convert<std::string>(); // ["string", 23] DynamicStruct aStruct; aStruct["First Name"] = "Junior"; aStruct["Last Name"] = "POCO"; aStruct["Age"] = 1; Var a1(aStruct); std::string res = a1.convert<std::string>(); // { "Age”: 1, "First Name": "Junior", "Last Name" : "POCO" } std::string str("42"); Var v1 = str; // "42" double d = v1; // 42.0 Var v2 = d + 1.0; // 43.0 float f = v2 + 1; // 44.0
  • 17. What Else is in the Var Box > Dynamic array, pair and struct (map) support (Poco::Dynamic::Pair/Struct) > JSON (de)serialization of the above > Empty value support (very handy with null DB fields) > Strict conversion checks
  • 18. namespace Poco { namespace Dynamic { class VarHolder { public: virtual ~VarHolder(); virtual void convert(int& val) const; // ... protected: VarHolder(); // ... }; template <typename T> // for end-user extensions class VarHolderImpl: public VarHolder { //... }; template <> // native and frequently used types specializations provided by POCO class VarHolderImpl<int>: public VarHolder { //... }; //... }} The Soul of the Machine (Poco::Dynamic::VarHolder)
  • 20. Let’s Dance class DataRequestHandler: public HTTPRequestHandler { public: void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) { response.setChunkedTransferEncoding(true); response.setContentType("text/xml"); ostream& ostr = response.send(); Session sess("SQLite", "sample.db"); ostr << RecordSet(sess, "SELECT * FROM Simpsons", XMLFormatter()); } };
  • 21. A Real World Example
  • 22. Is it REALLY Dynamic? In a sense,yes - values are instantiated at runtime. But they’re strongly typed and bound early. Dig deep enough and there is no such thing as dynamic.
  • 23. struct Person { std::string name; std::string address; int age; }; But what if I need performance? There is,of course,a lean and elegant static workaround. In fact,several of them ...
  • 24. namespace Poco { namespace Data { template <> class TypeHandler<Person> { public: static std::size_t size() { return 3; } static void bind(size_t pos, const Person& person, AbstractBinder::Ptr pBinder, Direction dir) { TypeHandler<std::string>::bind(pos++, person.name, pBinder, dir); TypeHandler<std::string>::bind(pos++, person.address, pBinder, dir); TypeHandler<int>::bind(pos++, person.age, pBinder, dir); } static void extract(size_t pos, Person& person, const Person& deflt, AbstractExtractor::Ptr p) { TypeHandler<std::string>::extract(pos++, person.name, deflt.name, p); TypeHandler<std::string>::extract(pos++, person.address, deflt.address, p); TypeHandler<int>::extract(pos++, person.age, deflt.age, p); } }; } } Scaffolding - wrap Person into a TypeHandler
  • 25. Person person = { "Bart Simpson", "Springfield", 12 }; session << "INSERT INTO Person VALUES(?, ?, ?)", use(person); std::vector<Person> people; session << "SELECT Name, Address, Age FROM Person",into(people), now; And Life is Good Again std::string name, address; int age; session << "INSERT INTO Person VALUES(?, ?, ?)", use(name), use(address), use(age);
  • 26. using namespace std; using namespace Poco; typedef Tuple<string, string, int> Person; typedef vector<Person> People; People people; people.push_back(Person("Bart Simpson", "Springfield", 12)); people.push_back(Person("Lisa Simpson", "Springfield", 10)); session << "INSERT INTO Person VALUES(?, ?, ?)", use(people), now; people.clear(); session << "SELECT Name, Address, Age FROM Person", into(people), now; But wait,there’s more!
  • 27. Nothing but pulling so far :-( Push,or my money back ! SELECT * FROM Simpsons
  • 28. Poco::Net::HTTPServer When Push comes to Shove ... RecordSet WebSocket RowFormatter Callback Poco::Dynamic::Var Event RegisterConnect Data Statement
  • 29. DBEventHandler():_session("SQLite", "sample.db"), _notifier(_session) { _notifier.insert += delegate(this, &DBEventHandler::onInsert); _notifier.update += delegate(this, &DBEventHandler::onUpdate); } void DBEventHandler::onInsert(const void* pSender) { Notifier* pN = notifier(pSender); Poco::Int64 rowID = pN->getRow(); std::cout << "Inserted row " << rowID << std::endl; notify(rowID); } Under the Hood - DB Events
  • 30. void DBEventHandler::notify(Poco::Int64 rowID) { std::ostringstream os; CSVFormatter cf; Statement stmt = (_session << "SELECT rowid, Name, Address, Age FROM Person WHERE rowid = ?", use(rowID), format(cf), now); os << RecordSet(stmt); _factory.handler().send(os.str()); } Under the Hood - DB Event Notification
  • 31. try { if (!_pWS) _pWS = new WebSocket(request, response); std::cout << "WebSocket connection established."; char buffer[1024]; int n; do { n = _pWS->receiveFrame(buffer, sizeof(buffer), _flags); } while (n > 0 || (_flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE); std::cout << "WebSocket connection closed." << std::endl; } catch (WebSocketException& exc) { /* ... */ } Under the Hood - WebSocket Loop
  • 32. class WebSocketRequestHandler { // ... void send(const std::string& buffer) { _pWS->sendFrame(buffer.data(), buffer.size(), _flags); } // ... }; Under the Hood - WebSocket Send
  • 33. function WebSocketOpen() { if ("WebSocket" in window) { ws = new WebSocket("ws://localhost:9980/ws"); ws.onopen = function() { ws.send("Hello, world!"); }; ws.onmessage = function(evt) { var arr = evt.data.split(","); if (arr.length >= 4) { updateTable(arr[0], arr[1], arr[2], arr[3]); } } }; Under the Hood - WebSocket,the browser end
  • 34. A Real Virtual World Example
  • 35. ACCU Overload Journal Articles http://accu.org/index.php/journals/1511 http://accu.org/index.php/journals/1502 Upcoming:“Dynamic C++” (June ACCU Overload)
  • 36. Last but not Least POCO > large, comprehensive, well-designed framework > designed for practical everyday use, with end-user in mind > makes C++ programming fun > 100% standard C++ > not reinventing the wheel (except when necessary ;-) https://github.com/pocoproject http://pocoproject.org
  • 37. got POCO?C++ PORTABLE COMPONENTS http://pocoproject.org alex@pocoproject.org