2023-11-30

tcl-monetdbe v0.2.0

 tcl-monetdbe


Tcl extension and TDBC driver for MonetDB Embedded.

MonetDB Embedded (MonetDB/e) 已經出現了一段時間,是 MonetDB 的 embedded solution。因為 MonetDB 我只是用來測試一些想法,所以之前一直沒有使用 MonetDB/e 的場合。

不過因為電腦上有裝 MonetDB 而且我也有安裝 MonetDB embedded library,所以考慮了一下,最近嘗試寫一個 Tcl extension 測試看看使用的情況。

2023-11-23

tdbc::mysql

最近我在整理自己的作業環境,這才發現 libmariadb-devel 對於 tdbc::mysql 而言是非必要的(以前因為 so suffixes 的關係需要裝,但是其實 tdbc::mysql 已經修正了,只是我沒注意到)。下面就是目前的 code:

static const char *const mysqlStubLibNames[] = {
    /* @LIBNAMES@: DO NOT EDIT THESE NAMES */
    "mariadbclient", "mariadb", "mysqlclient_r", "mysqlclient", "mysql", NULL
    /* @END@ */
};

/* ABI Version numbers of the MySQL API that we can cope with */

static const char mysqlSuffixes[][4] = {
    "", ".3", ".21", ".20", ".19", ".18", ".17", ".16", ".15"
};

如果說 MariaDB 是為了防止 Oracle 更改 MySQL 的授權而成立的,可是那為什麼 Michael Widenius 除了基金會,還又成立了一家企業?嘴上說我不是要用 MySQL 或者是 MariaDB 賺錢,實際上的行為卻完全相反,這是一個與說法衝突的行為(還可以參考 Uproar: MariaDB Corp. veers away from open source)。如果採用 MySQL 是被騙第一次,那 MariaDB 被騙第二次的人就應該要自我檢討了。我是說如果你擔心 Oracle 會對 MySQL 做出什麼損壞開放原始碼的事情,那麼 Michael Widenius 也可以重施故技,又賣掉 MariaDB 企業或者是上市賺取利益。

也就是說,我不認為應該要採用 MySQL 或者是 MariaDB。當然不是所有人都可以直接切換到其它的資料庫,這個時候可以考慮採用 MySQL protocol 並且高度相容的其它資料庫,在這個情況下,client 端的 source code 的變動理論上要很少,而 server 端則是換掉 MySQL 或者是 MariaDB,採用其它相容方案的資料庫。

在這個情況下,MySQL/MariaDB client API 是很重要的,而又剛好 MySQL/MariaDB client API 極大多數是 LGPL 或者是較為寬鬆的條款,只要採用動態連結的使用方式就可以在商業環境下使用,所以保留 MySQL/MariaDB client library,然後從MySQL 或者是 MariaDB 遷移出去。 

不過如果是因為學習 LAMP 架構而需要安裝一個資料庫,或者是撰寫開放原始碼的軟體,那麼 MySQL 與 MariaDB 我想可以考慮 MariaDB;理由也很簡單,因為大多數的 Linux distribution 都有內建的套件可以安裝(只是版本可能會比較舊不是最新的)。然後要小心資料庫專屬的功能,小心的避掉廠商鎖定的風險。

2023-11-22

tkimg 1.4.16

tkImg

 

tkimg 提供了更多影像格式的支援 (BMP, GIF, ICO, JPEG, PCX, PNG, PPM, PS, SGI, SUN, TGA, TIFF, XBM, XPM),最近釋出了 1.4.16 的新版本。

2023-11-15

DuckDB and ODBC

 DuckDB 是一套 in-process SQL OLAP database management system,所以是使用 DuckDB 在單機分析數據,也可以內嵌到應用程式。

因為有提供 ODBC interface,所以我使用 TDBC-ODBC 測試一下是否可以連線。

下載後解開壓縮檔,將二個檔案放在某個目錄(我是放在家目錄下的 Programs)。

首先在 Linux 執行需要有安裝 unixODBC。雖然 DuckDB 有提供 unixodbc_setup.sh 可以建立設定檔,不過需要python 以及相關的函式庫有安裝,所以我在執行時發生錯誤。不過只是要建立 ODBC 設定,DuckDB 在文件上也有提供相關的內容,所以自行在家目錄下建立以下二個檔案即可。

.odbc.ini

[DuckDB]
Driver = DuckDB Driver
Database=:memory:

.odbcinst.ini

[ODBC]
Trace = yes
TraceFile = /tmp/odbctrace

[DuckDB Driver]
Driver = /home/danilo/Programs/libduckdb_odbc.so

接下來就寫一個簡單的 script 測試。

package require tdbc::odbc

set connStr "DSN=DuckDB;"
if {[catch {tdbc::odbc::connection create db $connStr}]} {
   puts "Connection failed."
   exit
}

set statement [db prepare {SELECT VERSION() as version}]

puts "DuckDB version:"
$statement foreach row {
    puts [dict get $row version]
}

$statement close
db close

如果有印出 DuckDB 的版本,就表示可以透過 ODBC 來使用 DuckDB 了。

2023-11-14

tclcubrid v0.9.6

Source code
tclcubrid


附帶一提,要注意的是,CUBRID 使用 NCURSES 5 API,所以在 openSUSE 上使用,如果 NCRUSES 版本已升級到 6, 那麼需要安裝 NCURSES 6 所提供的與 5 ABI 相容的函式庫:

sudo zypper in libncurses5

我看了一下 tclcubrid 在 CUBRID 11.3 的執行情況,發現會有問題,所以更新了 CCI header files 嘗試解決問題;以及 CUBRID 10.2 有加入 JSON type,我在 v0.9.6 也嘗試加入 JSON type 的支援。

2023-11-03

openSUSE: Lighttpd and Tcl CGI

Lighttpd 是一款以 BSD 授權條款開源的網頁伺服器, 設計目的以安全、快速、小巧為主要設計理念。Lighttpd 和 Nginx 都是主打性能(二者的效能在伯仲之間)的網頁伺服器, 同時在使用情況上有一定範圍的重覆,只是 Lighttpd 在開始搶佔市佔率的時候被發現有一些 memory leak 的問題, 雖然在之後陸陸續續問題有所修正,但是在之後已無法取得更多的市佔率。

即使如此,當使用的情況主要是以靜態網頁為主並且不需要太多功能(Lighttpd 的 memory leak 主要發生在動態網頁, 而 Lighttpd 在靜態網頁方面十分高效),或者是在硬體有一些限制的情況下,需要設定簡單、輕量級的網頁伺服器, 就十分適合使用 Lighttpd。另外,和 Nginx 不同的是,Lighttpd 同時支援 CGI 與 FastCGI。

Install Lighttpd (@openSUSE):

sudo zypper install lighttpd

注意:Lighttpd 的 conf 目錄在 openSUSE 權限設定為 640,所以一般使用者無法直接讀取。


使用下列的指令查看 Lighttpd 的版本資訊,有 ssl 字樣表示支援 SSL。

sudo lighttpd -v

接下來使用自簽憑證設定 HTTPS。
首先建立 ssl.conf 設定檔:

[req]
prompt = no
default_md = sha256
default_bits = 2048
distinguished_name = dn
x509_extensions = v3_req

[dn]
C = TW
ST = Taiwan
L = Taipei
O = Orange Inc.
OU = IT Department
emailAddress = admin@example.com
CN = localhost

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.localhost
DNS.2 = localhost
IP.1 = 127.0.0.1

透過指令建立開發測試用途的自簽憑證:

openssl req -x509 -new -nodes -sha256 -utf8 -days 3650 \
-newkey rsa:2048 -keyout lighttpd.key -out lighttpd.csr -config ssl.conf

可以透過以下指令查看 lighttpd.csr 內容:

openssl x509 -in lighttpd.csr -text

使用下列的指令產生 lighttpd.pem:

cat lighttpd.key lighttpd.csr > lighttpd.pem

建立 /etc/lighttpd/ssl 目錄,將 lighttpd.pem 複製到 /etc/lighttpd/ssl 目錄下。

修改 /etc/lighttpd/modules.conf,加入下列的內容:

server.modules = (
#  "mod_rewrite",
  "mod_access",
#  "mod_auth",
#  "mod_authn_file",
#  "mod_redirect",
#  "mod_setenv",
#  "mod_alias",
   "mod_openssl",
)

修改 /etc/lighttpd/lighttpd.conf,加入下列的內容:

$SERVER["socket"] == ":443" {
        ssl.engine = "enable"
        ssl.pemfile = "/etc/lighttpd/ssl/lighttpd.pem"
        server.name = "localhost"
        server.document-root = "/srv/www/htdocs/"
}

Lighttpd 自 1.4.56 開始支援 HTTP/2(目前預設值為啟用)。
如果你想要嘗試 enable/disable HTTP/2,使用下列的設定:

server.feature-flags += ("server.h2proto" => "enable")

CGI

接下來加入 CGI 支援。

修改 /etc/lighttpd/modules.conf,修改並加入下列的內容:

server.modules = (
#  "mod_rewrite",
  "mod_access",
#  "mod_auth",
#  "mod_authn_file",
#  "mod_redirect",
#  "mod_setenv",
   "mod_alias",
   "mod_cgi",
   "mod_openssl",
)

修改 /etc/lighttpd/lighttpd.conf,加入下列的內容(因為要使用 Tcl 寫 CGI 程式, 所以要避免被視為靜態檔案):

static-file.exclude-extensions = ( ".tcl", ".php", ".pl", ".fcgi", ".scgi" )

Lighttpd 的 CGI 主要可以有二種風格的設定方式,一種是以 file extension 為主:

cgi.assign = ( ".tcl"  => "/usr/bin/tclsh",
               ".cgi" => "/usr/bin/tclsh" )

另外一種則是配合 mod_alias,將 CGI 程式放在 /cgi-bin:

# For execute CGI in /cgi-bin
alias.url += ( "/cgi-bin" => server_root + "/cgi-bin" )
$HTTP["url"] =~ "^/cgi-bin" {
   cgi.assign = ( "" => "" )
}

要使用何種風格的設定方式看使用者的喜好。

FastCGI

接下來是 FastCGI 的設定。
修改 /etc/lighttpd/modules.conf,修改並加入下列的內容:

server.modules = (
#  "mod_rewrite",
  "mod_access",
#  "mod_auth",
#  "mod_authn_file",
#  "mod_redirect",
#  "mod_setenv",
   "mod_alias",
   "mod_cgi",
   "mod_fastcgi",
   "mod_openssl",
)

spawn-fcgi

下面使用的方式配合 spawn-fcgi
我們需要撰寫 spawn-fcgi 的 systemd service,在 /usr/lib/systemd/system 目錄下建立 spawnfcgi.service,內容如下:

[Unit]
Description=Spawn FCGI service
After=nss-user-lookup.target

[Service]
Type=forking
Environment=WORKERS=1
ExecStart=/usr/bin/spawn-fcgi \
    -F ${WORKERS} \
    -u lighttpd \
    -g lighttpd \
    -a 127.0.0.1 -p 9000 \
    -P /var/run/%p.pid \
    -- /usr/bin/rivet-fcgi
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

(其中 -u 指定 user,-g 指定 group,隨著平台的不同可能有不同的設定。)

下面是測試我自己寫的工具 rivet-fcgi 的設定, 修改 /etc/lighttpd/lighttpd.conf

fastcgi.server = (
    ".rvt" =>
        (( "host" => "127.0.0.1",
            "port" => 9000,
            "docroot" => "/srv/www/htdocs"
        )),
    ".tcl" =>
        (( "host" => "127.0.0.1",
            "port" => 9000,
            "docroot" => "/srv/www/htdocs"
        ))
)

而後啟動(或重新啟動)spawn-fcgi 與 lighttpd 的服務,接著進行測試是否有正確設定。

php-fpm

php-fpm 設定檔在 openSUSE 主要為 /etc/php8/fpm/php-fpm.d/www.conf。在安裝以候使用預設值就可以順利執行, 如果有需要再視自己的需求修改。

修改 /etc/lighttpd/lighttpd.conf,加入下面的設定:

fastcgi.server = (
    ".php" =>
        (( "host" => "127.0.0.1",
            "port" => 9000,
            "docroot" => "/srv/www/htdocs"
        ))
)

而後啟動(或重新啟動)spawn-fcgi 與 lighttpd 的服務,接著進行測試是否有正確設定。 在 /srv/www/htdocs 目錄下建立 info.php:

<?php

phpinfo();

?>

如果瀏緊 info.php 可以得到資訊,就表示環境架設成功。

2023-11-02

Apache Rivet 3.2.3

 Apache Rivet 釋出了  3.2.x 系列的新版本,3.2.3。

下面是這個版本的更動:

  • Replaced CONST84 definitions with CONST86 in C code
  • Fixed [::rivet::raw_post] that failed when the POST request had no sections defined (contribution provided by Scott Pitcher)
  • Now virtual host interpreters log message into their log files also during ChildInitScript stage