บทนำ
วันก่อนไปส่อง facebook fanpage ขาเดฟ ซึ่งเป็นแหล่งร่วมตัวเทพ ในวงการ developer ได้โพสเกี่ยวกับส่วนขยาย(extension) ของ postgres ที่ชื่อว่า plv8 ที่ช่วยให้คุณสามารถเขียนฟังก์ชันและทริกเกอร์ด้วยภาษา JavaScript ได้ โดยใช้ V8 JavaScript engine ที่พัฒนาโดย Google
แล้วมันดียังไง
- ใช้ JavaScript ในฐานข้อมูล: เขียนโค้ด JavaScript ที่ทำงานโดยตรงใน PostgreSQL
- ประสิทธิภาพสูง: V8 engine มีประสิทธิภาพสูง ทำให้การประมวลผลเร็วกว่าภาษาอื่นๆ เช่น PL/pgSQL
- ความยืดหยุ่น: สามารถใช้คุณสมบัติของ JavaScript เช่น closures, high-order functions ได้
- JSON processing: เหมาะสำหรับการทำงานกับข้อมูล JSON ใน PostgreSQL
- NPM packages: สามารถใช้ JavaScript libraries จาก NPM ได้
การใช้งาน
-ติดตั้ง plv8 extension:
CREATE EXTENSION plv8
- การสรา้งและเรียกใช้ฟังก์ชั่น:
--สรา้งฟังก์ชั่น hellow_world ในการคืนข้อความ "Hello, World!"
CREATE FUNCTION hello_world() RETURNS text AS $$
return "Hello, World!";
$$ LANGUAGE plv8;
--การเรียกใช้ function hello_world--
SELECT hello_world();
- ฟังก์ชันที่ทำงานกับ JSON และใช้ JavaScript Array methods:
CREATE OR REPLACE FUNCTION filter_and_transform_users(users json) RETURNS json AS $$
const userArray = JSON.parse(users);
const result = userArray
.filter(user => user.age > 18)
.map(user => ({
fullName: `${user.firstName} ${user.lastName}`,
isAdult: user.age >= 21,
emailDomain: user.email.split('@')[1]
}));
return JSON.stringify(result);
$$ LANGUAGE plv8;
-- ตัวอย่างการใช้งาน
SELECT filter_and_transform_users('[
{"firstName": "John", "lastName": "Doe", "age": 25, "email": "john@example.com"},
{"firstName": "Jane", "lastName": "Smith", "age": 17, "email": "jane@test.com"},
{"firstName": "Bob", "lastName": "Johnson", "age": 30, "email": "bob@example.com"}
]');
- ฟังก์ชันที่ใช้ closure และ state ระหว่าง invocations:
CREATE OR REPLACE FUNCTION create_counter() RETURNS json AS $$
const state = plv8.initialize_state();
if (!state.counter) state.counter = 0;
function increment() {
state.counter++;
return state.counter;
}
function decrement() {
state.counter--;
return state.counter;
}
function reset() {
state.counter = 0;
return state.counter;
}
return JSON.stringify({increment, decrement, reset});
$$ LANGUAGE plv8;
-- ตัวอย่างการใช้งาน
DO $$
const counter = JSON.parse(plv8.execute('SELECT create_counter()')[0].create_counter);
plv8.elog(NOTICE, counter.increment()); // 1
plv8.elog(NOTICE, counter.increment()); // 2
plv8.elog(NOTICE, counter.decrement()); // 1
plv8.elog(NOTICE, counter.reset()); // 0
$$ LANGUAGE plv8;
- ฟังก์ชันที่ใช้ external library (ต้องติดตั้ง library ก่อน):
CREATE OR REPLACE FUNCTION validate_email(email text) RETURNS boolean AS $$
const validator = require('email-validator');
return validator.validate(email);
$$ LANGUAGE plv8;
-- ตัวอย่างการใช้งาน
SELECT validate_email('user@example.com');
SELECT validate_email('invalid-email');
- ทริกเกอร์ที่ใช้ PL/V8:
-- สรา้งตารางเก็บชื่อผู้ใช้งาน
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT,
email TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
--สร้างฟังก์ชั่น validate_user() ในการตรวจสอบชื่อผู้ใช้งาน และ email
CREATE OR REPLACE FUNCTION validate_user() RETURNS trigger AS $$
if (!NEW.username || NEW.username.length < 3) {
plv8.elog(ERROR, 'Username must be at least 3 characters long');
}
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(NEW.email)) {
plv8.elog(ERROR, 'Invalid email format');
}
return NEW;
$$ LANGUAGE plv8;
--สร้าง trigger ในการเรียกใช้ฟังก์ชั่น validate_user() ในการตรวจสอบชื่อผู้ใช้งาน และ email
CREATE TRIGGER user_validation_trigger
BEFORE INSERT OR UPDATE ON users
FOR EACH ROW EXECUTE FUNCTION validate_user();
-- ตัวอย่างการใช้งาน
INSERT INTO users (username, email) VALUES ('jo', 'john@example.com'); -- จะ error
INSERT INTO users (username, email) VALUES ('john', 'invalid-email'); -- จะ error
INSERT INTO users (username, email) VALUES ('john', 'john@example.com'); -- จะสำเร็จ
มีอะไรต้องระวังไหม
- ต้องติดตั้ง PL/V8 extension เพิ่มเติม
- การใช้ JavaScript อาจทำให้การ debug ยากขึ้น
- ต้องระวังเรื่องความปลอดภัย เพราะ JavaScript สามารถเข้าถึงระบบไฟล์ได้
ส่งท้าย
ส่วนขยาย plv8 ช่วยให้ทาง developer สามารถสร้างฟังก์ชั่นที่ทำงานเฉพาะ ซึ่งฝั่ง developer มีความชำนาญ JavaScript อยู่แล้วโดยไม่ต้องพึ่ง Database Admin (ซึ่งส่วนใหญ่จะไม่ค่อยชำนาญภาษา pl/pgsql) อีกทั้งยังสามารถเรียก npm เพื่อเพิ่มความสามารถผ่าน javscript อย่างที่ผมเคยบอกว่า postgres เป็นทุกอย่างให้เธอแล้ว
Top comments (0)