PLGO

PostgreSQL уже достаточно долго занимает одно из лидирующих мест среди СУБД. Помимо использования SQL он позволяет создавать хранимые процедуры на других языках программирования таких как Perl, C, Java, JavaScript и др. В том числе и на GOLANG. Для этого существует plgo, который позволяет создавать расширения для PostgreSQL с хранимыми процедурами на GOLANG. Оно генерирует враппер для кода, файлы extention для PostgreSQL и компилирует пакет

Для начала работы нужно установить расширение:

go get -u github.com/microo8/plgo/... 

После этого можно приступить к написанию хранимых процедур на plgo, что сделать достаточно просто. Для этого нужно сделать пакет, в котором будут объявлены все необходимые процедуры. Пакет должен иметь имя main

package main 

import (
  "log"
  "strings"
  "github.com/microo8/plgo"
)

func Meh() {
    //NoticeLogger позволяет напечатать сообщение в лог
    logger := plgo.NewNoticeLogger("", log.Ltime|log.Lshortfile)
    logger.Println("meh")
}

// конкатенация всех значений выбранного столбца заданной таблицы

func ConcatAll(tableName, colName string) string {
    //ErrorLogger for printing error messages to elog
    logger := plgo.NewErrorLogger("", log.Ltime|log.Lshortfile)

    db, err := plgo.Open() //open the connection to DB
    if err != nil {
        logger.Fatalf("Cannot open DB: %s", err)
    }

    defer db.Close() //подключение к базе должно быть закрыто 
    query := "select " + colName + " from " + tableName 

    stmt, err := db.Prepare(query, nil) // подготовка запроса
    if err != nil {
        logger.Fatalf("Cannot prepare query statement (%s): %s", query, err)
    } 

    rows, err := stmt.Query() // выполнение запроса 
    if err != nil {
        logger.Fatalf("Query (%s) error: %s", query, err)
    } 

    var ret string 
    for rows.Next() { // цикл по всем строкам результирующего набора 
        var val string 
        rows.Scan(&val)
        ret += val
    }

    return ret
} 

// пример функции триггера, которая на вход принимает *plgo.TriggerData
// и должна возвратить *plgo.TriggerRow
func CreatedTimeTrigger(td *plgo.TriggerData) *plgo.TriggerRow { 
    td.NewRow.Set(4, time.Now()) //установка столбца под номеров 4 в now() 
    return td.NewRow //возврат измененной строки 
} 

// пример конкатенации массива строк 
func ConcatArray(strs []string) string {
    return strings.Join(strs, "")
} 

Для установки расширения нужно воспользоваться утилитой plgo: 

plgo [путь к пакету] 

В результате чего будет создана директория build со всем необходимым (Makefile, extention.sql,…) Запускаем установку:

cd build 
sudo make install

После выполнения установки можно использовать расширение в PostgreSQL:

CREATE EXTENSION myextention; 

Вызываем нашу функции конкатенации строк:

SELECT concatarray(ARRAY['foo','bar']); 

Получаем результат:

concatarray
-------------
foobar 
(1 row) 

Обращу особое внимание на использование горутин из plgo. Здесь не все так хорошо, plgo будет пытаться выделить памяти больше чем значение max_stack_depth, из-за чего могут быть проблемы. При помощи некоторых трюков это можно обойти, но я бы не советовал.

 

Тэги: go golang plgo postgresql базы данных


 


 
архив

подписка