PLV8 - The PostgreSQL web side

Embed Size (px)

Citation preview

PLV8The Postgresql web sideLucio [email protected]

Who I am

Delphi developer since 1999

IT Consultant

Front end web developer

Postgresql addicted

Nonantolando.blogspot.com lucio.grenzi lucio grenzi

Agenda

NoSQL db pros

PLV8 introduction

PLV8 implemented features

Json datatype in PostgreSQL

Why choose PostregreSQL instead of NoSQL db

NoSQL

Relations, no tables

Schema less

Json

Document based

Easy to understand

Schema flexibility (model documents to reflect application-level object)

PLV8: an introduction

plv8 is a shared library that provides a PostgreSQL procedural language powered by V8 JavaScript Engine. With this program you can write in JavaScript your function that is callable from SQL.

-http://pgxn.org/dist/plv8/-

javascript

Used everywhere

Language known by lots of devs

Simplicity. JavaScript is relatively simple to learn and implement.

Lots of extensions available

Why v8 engine

Developed and maintained by Google

open source high-performance JavaScript engine

written in C++

V8 can run standalone, or can be embedded into any C++ application

compiles and executes JavaScript source code

handles memory allocation for objects

garbage collects objects it no longer needs

Requirements

PG: version >= 8.4

V8: version >= 3.14.5

Step to follow in order to install it

Install Postgresql

Install v8

(PG 9.1 or newer) psql -d dbname -c "CREATE EXTENSION plv8"

createlang -d dbname plv8

psql -d dbname -c "CREATE LANGUAGE plv8"

Install plv8 on Debian/Ubuntu

apt-get install postgresql

apt-get install libv8

apt-get install postgresql-9.2-plv8

PLV8: a trusted language

non-core loadable language

interpreter is sandboxed

no way to load external processing modules from the file system

JavaScript modules can be loaded from the database itself

Lets code

\set underscore `cat underscore-min.js`create table plv8_modules(modname text primary key, load_on_start boolean, code text);

insert into plv8_modules values ('underscore',true,:'underscore'),

create or replace function plv8_startup()returns voidlanguage plv8as$$load_module = function(modname){ var rows = plv8.execute("SELECT code from plv8_modules " + " where modname = $1", [modname]); for (var r = 0; r < rows.length; r++) { var code = rows[r].code; eval("(function() { " + code + "})")(); } };$$;

Implemented features

Scalar function calls

Set returing function calls

Trigger function calls

Inline statement calls

Auto mapping between JS and database built-in types

Database access via SPI including prepared statements and cursors

Subtransaction

Utility functions

Window function API

Typed array

Remote debugger

Runtime environment separation across users in the same session

Start-up procedure

Dialects

Auto mapping between JS and database built-in types

Database types and JS types are mapped automaticallyoid

bool

int2

int4

int8

float4

float8

numeric

date

timestamp

timestamptz

bytea

Json (>= 9.2)

If the JS value looks compatible, then the conversion succeeds. Otherwise, PL/v8 tries to convert them via cstring representation. An array type is supported only if the dimention is one.

Subtransaction

plv8.subtransaction( func )plv8.execute() creates a subtransaction every time. If you need an atomic operation, you will need to call plv8.subtransaction() to create a subtransaction block.

try{ plv8.subtransaction(function(){ plv8.execute("INSERT INTO table1 VALUES(1)"); plv8.execute("INSERT INTO table1 VALUES(test)"); -- exception is raised });} catch(e) { ... rollback is executed and do alternate operation ...}

Utility functions

PL/v8 provides the following utility built-in functions.

plv8.elog(elevel, msg1[, msg2, ...]) plv8.quote_literal(str) plv8.nullable(str) plv8.quote_ident(str) plv8.elog emits message to the client or the log file. The elevel is one of

DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, LOG, INFO, NOTICE WARNING, ERROR

See the PostgreSQL manual for each error level.

Each functionality for quote family is identical to the built-in SQL function with the same name.

Typed array

Allow fast access to native memory, mainly for the purpose of their canvas support in browsers. PL/v8 uses this to map bytea (unsigned byte) and various array types to JavaScript array. IFor int2/int4/float4/float8 array type, PL/v8 provides direct access to each element by using PL/v8 domain types.

Currently there is no way to create such typed array inside PL/v8 functions. Only arguments can be typed array. You can modify the element and return the value.

CREATE FUNCTION int4sum(ary plv8_int4array) RETURNS int8 AS $$ var sum = 0; for (var i = 0; i < ary.length; i++) { sum += ary[i]; } return sum; $$ LANGUAGE plv8 IMMUTABLE STRICT;

SELECT int4sum(ARRAY[1, 2, 3, 4, 5]); int4sum

Remote debugger

PL/v8 supports v8 remote debugger.

To enable it at the compile time pass ENABLE_DEBUGGER_SUPPORT.

Once PL/v8 module is loaded (and the execution engine is initialized), PL/v8 accepts a remote debugger connection. If you have d8 from v8 package, run with --remote-debug --debug-port=35432 to attach the functions.

It is possible debug statement inside functions to set a breakpoint.

Runtime environment separation

In PL/v8, each session has one global JS runtime context. For the security reasons, if the user switches to another with SET ROLE command, a new JS runtime context is initialized and used separately. This prevents unexpected information leak risk.

Each plv8 function is invoked as if the function is the property of other object. This means "this" in each function is a JS object that is created every time the function is executed in a query. In other words, the life time and the visibility of "this" object in a function is only a series of function calls in a query. If you need to share some value among different functions, keep it in plv8 object because each function invocation has different "this" object.

Dialects

Currently two dialects are supportedCoffeeScript (plcoffee)

LiveScript (plls)

Dialects can be loaded via CREATE EXTENSION command ( On PostgreSQL >= 9.1 )

Json datatype

JSON is the lingua franca of the web

Introduced on Postgresql 9.2

Currently this is nothing more than a validating data type

PLV8 + Json = amazing new possibilitiesWorking directly with JSON and JavaScript has been all the rage in many of the NoSQL databases

A basic approach

CREATE or REPLACE FUNCTION json_string(data json, key text) RETURNS TEXT AS $$ var data = JSON.parse(data); return JSON.stringify(data[key]);$$ LANGUAGE plv8 IMMUTABLE STRICT;

SELECT id, data FROM things WHERE json_string(data,'name') LIKE 'Z%';

CREATE INDEX json_idx ON things (json_string(field,'name'));

Web development stack

Client side: backbone.js jquery.js

Server side: node.js

Database: PostgreSQL + PLV8

Pros:

Rapid prototyping

Easy to change

Model database as in-store memory

One table, key/data

No costs of switching language

Table like NOSql

CREATE EXTENSION plv8;CREATE TABLE things ( Id uuid PRIMARY KEY DEFAULT (uuid_generate_v4()), data json);

At the end ...

All very easy

All very fast

All very simple

Plv8 is stable for production

Constanly updated

Nosql db? No thanks

Risorse

http://code.google.com/p/plv8js/wiki/PLV8

http://adpgtech.blogspot.it/2013/03/loading-useful-modules-in-plv8.html

http://pgxn.org/dist/plv8/doc/plv8.html

http://interlinked.org/tutorials/postgresql.html

http://plv8-pgconfeu.herokuapp.com

Questions?

Title

Click to edit the outline text formatSecond Outline LevelThird Outline LevelFourth Outline LevelFifth Outline LevelSixth Outline LevelSeventh Outline LevelEighth Outline LevelNinth Outline Level

PGDay.IT 2013 25 Ottobre 2013 - Prato

di