2016-12-28

Tcl bindings for OpenAL (open audio library): tclopenal

Source code:
tclopenal


用途:
只是簡單的包裝 OpenAL 的 API,然後配合 tclmpg123 或者是 tclsndfile 來播放音樂檔案。因為 OpenAL 選項很多,所以我做了一些簡化假設(所以這是一個簡化的版本)。

然後 capture 的部份我遇到很麻煩的問題,因為 Windows 7 (64bit), Ubuntu 14.04 (VM) 無法找到可以使用的 capture device,openSUSE 可以找到但是開啟失敗。所以目前只有 playback 功能的部份。


更新:
Windows 7 要插入麥克風才會出現 device。

更新:
我大概知道為什麼會開啟 capture device 失敗了。

更新:
推送上去開啟 capture device OK 的 code。
但是只有執行測試沒問題,沒有實際錄音。

2016/12/29 更新:
目前的實作使用 1 source 1 buffer,如果播放比較大的音樂檔案會遇到問題才對。
目前不知道怎麼解決,所以我先 tag 一個 v0.1 的版本,然後研究以後再看能不能改善。

更新:
嘗試加入超過 1 個 buffer 的支援。

2016/12/30 更新:
加入更多關於使用超過 1 個 buffer 的支援。
tag 一個 v0.2 的版本。

2016-12-21

Tcl bindings for PulseAudio simple API: tpulsesimple v0.1

Source code


tpulsesimple


About

PulseAudio is a network-capable sound server program distributed by freedesktop.org.

The simple API is designed for applications with very basic sound playback or capture needs. It can only support a single stream per connection and has no handling of complex features like events, channel mappings and volume control.

This extension is Tcl bindings for PulseAudio simple API.


說明


用來測試 PulseAudio simple API。write 的部份使用播放 mp3 檔案的方式來測試,read 的部份只有做執行測試(沒有實際 record)。

2016-12-15

rl_json extension

rl_json - Extends Tcl with a json value type and a command to manipulate json values directly. Similar in spirit to how the dict command manipulates dictionary values, and comparable in speed


之前在 Tcler's wiki 發現的套件,他展示了一個我現在還不會的 Tcl extension 技巧,就是將 JSON 視為 value type (defines a new Tcl_Obj type to store the parsed JSON document)。

因為這個想法實在是太厲害了,我記錄一下這個套件。

2016-12-14

Tcltaglib v0.9

網站:

Tcltaglib


ChangeLog:
  • Upgrade TEA to 3.10

在試著使用 MSYS2/MinGW-W64 來編譯的時候,我發現會編譯失敗,不過升級 TEA 版本到 3.10 以後就可以解決。

所以我把 TEA 升版到 3.10。然後將 README.md 的說明寫的更清楚一些,所以重新出發,github 上的被我刪除重建了。然後將文件的更新也放到 Tcltaglib 的網頁上。

更新:
嗯…… 有東西沒更新到,所以我又重建了一次(囧),然後重新上傳檔案。

更新 x2:
狀態不太好,還是有東西沒更新到,重新更新一次。

2016-12-13

Tclmpg123

Source code:
tclmpg123


因為 MP3 的專利的關係,所以 libsndfile 的作者沒有寫關於 mp3 格式的部份(因為他開了一家公司來處理 libsndfile 的維護,所以如果 MPEG 組織找上門來索取專利費的話會帶來問題),如果要讀取 mp3,就要使用其它的 library。

所以 tclmpg123 就是用來透過 libmpg123 處理讀取 mp3 檔案的工作,然後再把讀出來的音訊訊號丟給 tcllibao 輸出。

2016-12-10

Tcllibao and Tclsndfile

Tcllibao:
source code

Tclsndfile:
source code


Tcl/Tk 已經有二個 audio extension 可以使用,一個是 Snack,一個是 SDL_mixer bindings for Tcl

Snack 其實原作者看起來已經沒有什麼更新,不過 Tcl/Tk 社群仍然有人持續在維護,是一個很普遍的套件。


我寫 tcllibao 和 tclsndfile 只是為了探索 Linux audio library 的使用方式。libsndfile 是讀取檔案以後拿到音訊資料,而 libao 用來將聲音輸出(還有其它的 library 可以用,例如 SDL_mixer)。

要注意的是,libao 使用 GPL 授權,所以我 tcllibao 使用同樣的授權方式。同樣的,libsndfile 使用 LGPL 授權,tclsndfile 我也使用同樣的授權方式。

下面就是我的測試程式:
#!/usr/bin/tclsh
#
# Using libao and libsndfile to play a wav/ogg file
#

package require libao
package require sndfile

if {$argc > 0} {
    set name [lindex $argv 0]
} else {
    puts "Please input filename."
    exit
}

if {[catch {set data [sndfile snd0 $name READ]}]} {
    puts "sndfile: read file failed."
    exit
}
set encoding [dict get $data encoding]

# only for test seek
snd0 seek 0 SET

libao::ao initialize
set id [libao::ao default_id]

set bits 16
switch $encoding {
 {pcm_16} {
    set bits 16
 }
 {pcm_24} {
    set bits 24
 }
 {pcm_32} {
    set bits 32
 }
 {pcm_s8} {
    set bits 8
 }
 {pcm_u8} {
    set bits 8
 }
 default {
    set bits 16
 }
}

libao::ao open_live $id -bits $bits \
  -rate [dict get $data samplerate] \
  -channels [dict get $data channels] -byteformat 4

# libao needs use read_short to get data
while {[catch {set buffer [snd0 read_short]}] == 0} {
    libao::ao play $buffer
}

snd0 close
libao::ao close
libao::ao shutdown



更新: 我發現 tclsndfile README.md 我有打錯說明,所以刪掉重新建了一個新的上去 github。


2016/12/12
嘗試在 Windows 7 (64bit) 使用 MSYS2/MinGW-W64 編譯與使用測試,我把遇到的問題跟解法記錄在 github README.md。

2016-12-08

tclcubrid v0.9.4

Source code

tclcubrid

About


CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.

Main changelog

  1. Add Date/Time types with timezone support

這個版本增加 Date/Time types with timezone 的支援。

2016-12-05

Tclunqlite v0.3.2

檔案放置網頁


Tclunqlite

About

This is the UnQLite extension for Tcl using the Tcl Extension Architecture (TEA).

UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL (Key/Value store and Document-store) database engine. This extension provides an easy to use interface for accessing UnQLite database files from Tcl.

Main Change

  1. Update UnQLite version to 1.1.7

說明


這是一個小更新版本,更新 UnQLite 的版本。

2016-11-29

1-9位數不重複印出來 (練習問題)

使用者輸入1 印1-9
使用者輸入2 印1-98 (11, 22, 33等重複的不印)
使用者輸入3 印1-987 (121, 988, 667等有重複的不印)


#!/usr/bin/tclsh
#
# Test on Tcl 8.6
#

puts -nonewline "Please input a number: "
flush stdout
gets stdin number
if {$number <= 0 || $number >= 10} {
   puts "The range is 1 - 9."
   exit
}

set max [expr 10 ** $number]

puts "\nNow get the result:"
puts "==========="
puts "Start"
puts "==========="
puts -nonewline "1"
for {set i 2} {$i < $max} {incr i} {
    set var [regexp "1.*1|2.*2|3.*3|4.*4|5.*5|6.*6|7.*7|8.*8|9.*9|0.*0" $i]
    if {$var != 1} {
        puts -nonewline ", $i"
    }
}
puts "\n==========="
puts "End"
puts "==========="

也可以使用 lsort -unique 建立 set 來解題。
puts -nonewline "Please input a number: "
flush stdout
gets stdin number
if {$number <= 0 || $number >= 10} {
   puts "The range is 1 - 9."
   exit
}

set max [expr pow(10, $number)]
set result [list]

puts "\nNow get the result:"
puts "==========="
puts "Start"
puts "==========="
for {set i 1} {$i < $max} {incr i} {
     set tmpstring [format %s $i]
     set tmpList [lsort -unique [split $tmpstring ""]]

     if {[string length $tmpstring] == [llength $tmpList]} {
         lappend result $i
     }
}
puts [join $result ", "]
puts "\n==========="
puts "End"
puts "==========="

也可以用 permutations 的方式來解題,下面是 Tcl 的版本:
#!/usr/bin/env tclsh

proc permutations { list size } {
    if { $size == 0 } {
        return [list [list]]
    }

    set retval {}
    for { set i 0 } { $i < [llength $list] } { incr i } {
        set firstElement [lindex $list $i]
        set remainingElements [lreplace $list $i $i]
        foreach subset [permutations $remainingElements [expr { $size - 1 }]] {
            lappend retval [linsert $subset 0 $firstElement]
        }
    }

    return $retval
}

puts -nonewline "Please input a number: "
flush stdout
gets stdin number
if {$number <= 0 || $number >= 10} {
    puts "The range is 1 - 9."
    exit
}

set allresult [list]
for {set i 1} {$i <= $number} {incr i} {
    set res [permutations [list 0 1 2 3 4 5 6 7 8 9] $i]
    set allresult [list {*}$allresult {*}$res]
}

puts -nonewline "1"
set len [llength $allresult]
for {set i 2} {$i < $len} {incr i} {
    set r [lindex $allresult $i]
    set first [lindex $r 0]
    if {[string compare $first "0"]==0} {
        continue
    }    
    puts -nonewline ", "    
    puts -nonewline [join $r ""]
}
puts "\n"
flush stdout

2016-11-18

tcl.mqttc

Source code


tcl.mqttc

About


This Tcl extension is based on Paho MQTT C Client, but only support synchronous API and basic SSL/TLS support (server needs setup needClientAuth to false).

Test server: Apache ActiveMQ

我發現 Apache ActiveMQ 有支援 MQTT,所以使用 Paho MQTT C Client 的實作,包裝了一個 Tcl extension 來測試。

TLS/SSL 只支援 Server authentication/Anonymous connection,Mutual authentication 則有問題(應該說我不知道怎麼正確設定,稍微搜尋了一下網路上的解法,還是設不起來),所以只有放上去關於 Server authentication 的部份。


2016/11/19 更新
我重新檢視了一下 log,發現我好像沒有正確的加入資料到 server 端的 trueStore,重做一次以後就可以正常工作。所以我把 Mutual authentication 相關的部份也推送上去 github 了。

2016-11-14

tclcubrid v0.9.3

Source code

tclcubrid

About


CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.

Main changelog

  1. Free memory when connect fail

 這是一個小更新的版本。

2016-11-11

MonetDB ODBC (Linux/openSUSE) test

MonetDB ODBC driver 的部份,首先必須要先安裝 unixODBC,然後編譯的時候需要有編譯 ODBC driver。 unixODBC 需要設定二個檔案。/etc/unixODBC/odbc.ini 與 /etc/unixODBC/odbcinst.ini。


首先是 odbcinst.ini 的內容:
[MonetDB]
Description     = ODBC driver for MonetDB server
Driver          = /usr/local/lib64/libMonetODBC.so
Setup           = /usr/local/lib64/libMonetODBCs.so
FileUsage       = 1

再來是 odbc.ini,
[MonetDB]
Description     = MonetDB
Driver          = MonetDB
Trace           = No
TraceFile       =
Database        = demo
Host            = localhost
UserName        = monetdb
Password        = monetdb
Port            = 50000
ConfigFile      =

我們使用 TDBCODBC 進行驗證:
package require tdbc::odbc

set connStr "DSN=MonetDB; UID=monetdb; PWD=monetdb;"
tdbc::odbc::connection create db $connStr

set statement [db prepare {create table person (id integer, name varchar(40))}]
$statement execute
$statement close

set statement [db prepare {insert into person values(1, 'leo')}]
$statement execute
$statement close

set statement [db prepare {insert into person values(2, 'yui')}]
$statement execute
$statement close

set statement [db prepare {SELECT * FROM person}]

$statement foreach row {
    puts [dict get $row id]
    puts [dict get $row name]
}

$statement close

set statement [db prepare {drop table person}]
$statement execute
$statement close

2016-11-06

tclcubrid v0.9.2

Source code

tclcubrid

About


CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.

Main changelog

  1. Update Thread_Exit method

 這是一個小更新的版本。

2016-11-04

tclcubrid v0.9.1

Source code:
tclcubrid


About:

CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.


Main changelog:

  1. Update TDBC configure method

 這是一個小更新的版本,更新 TDBC configure method(加入 -readonly option)。

2016-10-25

pgintcl and PREPARE

pgintcl 是純粹使用 Tcl 所撰寫的 PostgreSQL client。

不過沒有實作 PQprepare 相關的部份,那麼如果要使用 prepared statement,要怎麼使用?答案是使用 PostgreSQL 的 PREPARE statement。

下面是一段簡單的 test code 的內容:
package require pgintcl

# connect to database
set db [pg_connect -conninfo "dbname=danilo user=danilo password=danilo"]

pg_execute $db "CREATE TABLE IF NOT EXISTS contact (id int, name varchar(200), primary key(id));"
pg_execute $db "PREPARE test1 AS INSERT INTO contact (id, name) VALUES (\$1, \$2);"
set res [pg_describe_prepared $db test1]
# Although Get the param type, it is the Object IDs for the Postgres data types
pg_result $res -paramTypes
pg_result $res -clear

# Need setup text or binary format, here is setup to all TEXT format
set res [pg_exec_prepared $db test1 TEXT  TEXT 1 "Raynor"]
pg_result $res -status
pg_result $res -clear

# Need setup text or binary format, here is setup to all TEXT format
set res [pg_exec_prepared $db test1 TEXT  TEXT 2 "Tassadra"]
pg_result $res -status
pg_result $res -clear

# Need setup text or binary format, here is setup to all TEXT format
set res [pg_exec_prepared $db test1 TEXT  TEXT 3 "Kavin"]
pg_result $res -status
pg_result $res -clear

pg_execute $db "PREPARE test2 AS select * from contact;"
set res [pg_describe_prepared $db test2]
# Get column number and attributes
pg_result $res -numAttrs 
pg_result $res -lAttributes
# Get param types
pg_result $res -paramTypes
pg_result $res -clear

set res [pg_exec_prepared $db test2 TEXT  TEXT]
# Get the result numbers
pg_result $res -numTuples
# Returns the query results as a Tcl dictionary
pg_result $res -dict

pg_execute $db "DROP TABLE IF EXISTS contact;"

pg_disconnect $db

這樣就可以在 pgintcl 中使用 prepared statement 了。另外 PostgreSQL 不是使用 ?,而是使用 $1, $2 來代表。

2016-10-23

Tclunqlite v0.3.1

檔案放置網頁


Tclunqlite

About

This is the UnQLite extension for Tcl using the Tcl Extension Architecture (TEA).

UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL (Key/Value store and Document-store) database engine. This extension provides an easy to use interface for accessing UnQLite database files from Tcl.

Main Change

  1. Avoid va_arg read if it is last (merge UnQLite code)

說明


這是一個小更新版本,merge UnQLite 的一個小更新。

2016-10-22

tclcubrid v0.9

Source code:
tclcubrid


About:

CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.


Main changelog:

  1. Add multiset type support
  2. CLOB/BLOB size limitation change to 1048576

加入 multiset 的支援,並且更新 CLOB/BLOB 的大小限制。

tcljsonnet v0.5

首頁:
tcljsonnet


主要更新:
將 Jsonnet code base 版本升到 v0.9.0 版。

2016-10-04

tclcubrid v0.8

Source code:
tclcubrid


About:

CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.


Main changelog:

  1. Cleanup TDBC code
  2. Update README.md

簡單的更新了 TDBC paramtype 部份的 code,省略一些無效處理的部份。

2016-09-28

tclJBlend

tclJBlend

a fork of TclBlend, a Tcl extension that uses JNI to communicate with a Java interpreter.



在今天 Wiki 更新資訊以後,有提供一個 binary 檔案, 所以我有下載來測試看看。同時我也更新了 TDBCJDBC 來進行簡單的測試。


2016-10-02 更新
我發現我是個豬頭,所以更新了對於 TclBlend 與 TclJBlend 的判斷方式。

簡單的說一開始我的寫法是錯的(檢查的環境變數並不正確),但是如果 TclBlend 和 TclJBlend 是共存的,那麼我還是可以正確的啟動 TDBCJDBC,也就是我的檢查方式並不正確,只是我以為我寫的是對的。

今天我在整理環境的時候發現錯誤,研究了 jtclsh 的寫法以後,更新了要檢查的環境變數,然後也整個刪掉以後再重建 TDBCJDBC 的 repository。

2016-09-21

GO and Tcl

gothic - Tcl/Tk Go bindings
Example of a Tcl extension in Go


在 Tcler's Wiki 上有人新增加了一些 GO 與 Tcl 的資料,我做一下記錄。其中 gothic 是從 GO 呼叫 Tcl/Tk。

Tclunqlite v0.3

檔案放置網頁


Tclunqlite

About

This is the UnQLite extension for Tcl using the Tcl Extension Architecture (TEA).

UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL (Key/Value store and Document-store) database engine. This extension provides an easy to use interface for accessing UnQLite database files from Tcl.

Main Change

    1. Merge code to fix UnQLite bug (port bug fixes from vedis)
    2. Enable multi-thread mutex for memory allocation, fix page ref bug
    3. Change create and exists collection logic
    4. Identify null and empty string of json value

      說明


      UnQLite amalgamed version 有些修正沒有 merge 進去,我參考 github 上的 source code merge 進來這些修正。

      2016-09-13

      Tclunqlite v0.2.8

      檔案放置網頁


      Tclunqlite

      About

      This is the UnQLite extension for Tcl using the Tcl Extension Architecture (TEA).

      UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL (Key/Value store and Document-store) database engine. This extension provides an easy to use interface for accessing UnQLite database files from Tcl.

      Main Change

      1. Add doc_update_record method
      2. Update UnQLite source code: add db_record_update method

      說明


      更新 source code,加入 UnQLite 這一段時間以來的變更。同時加入新的 method doc_update_record 來反應 source code 的變化。

      2016-09-12

      tclcubrid v0.7

      Source code:
      tclcubrid


      About:

      CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

      tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.


      Main changelog:
      1. TDBC "tdbc::cubrid::connection create" parameters changed
        It is an INCOMPATIBILITY change! User maybe need update source code.
      2. cubrid HANDLE add parameter -property
        It is a POTENTIAL INCOMPATIBILITY change!
      3. Using cci_connect_with_url_ex to replace cci_connect_ex

      更新 source code,使用 cci_connect_with_url_ex 取代 cci_connect_ex,並且加入相關部份的變化。

      稍微閱讀 CUBRID HA 的文件以後,發現 CUBRID client 的部份使用  cci_connect_with_url_ex 來傳遞與 HA 有關的參數,雖然我不知道我的實作是不是適用,但是還是先改成使用 cci_connect_with_url_ex 來連線。

      tclcubrid v0.6

      Source code:
      tclcubrid


      About:

      CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

      tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.


      Main changelog:

      1. Add last_insert_id method

      當使用 AUTO_INCREMENT 的時候,可以用來查詢最後一個增加的 id。如果傳回來的是空字串,我目前是用傳回 0 來處理(不太確定這是不是正確的處理方式)。

      2016-09-01

      tclcubrid v0.5

      Source code:
      tclcubrid


      About:

      CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

      tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.


      Main changelog:
      1. TDBC: let user can use -isolation option when create a connection handle
      2. Update README.md

      更新 tdbc::cubrid,加入 -isolation option,讓使用者可以在建立連線時設定 isolation level。

      PS.
      更新,因為我發現我在 commit 出現很蠢的錯誤,所以刪除掉 github 上的 repository 重新建立了一個,版本則一樣是 v0.5。

      2016-08-31

      tclcubrid v0.4

      Source code:
      tclcubrid


      About:

      CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

      tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.


      Main changelog:
      1. Update test cases
      2. Update README.md


      原始碼並沒有更動,只有更新 test cases,加入更多基本測試。

      2016-08-18

      tclcubrid v0.3

      Source code:
      tclcubrid


      About:

      CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

      tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.


      Main changelog:

      1. Add sequence type support
      2. Add set type support


      嘗試加入更多 type 的支援。

      2016-08-17

      tclcubrid v0.2

      Source code:
      tclcubrid


      About:

      CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

      tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.


      Main changelog:
      1. Using cci_connect_ex to replace cci_connect_3_0 method
      2. Add monetary type support
      3. Add enum type support


      替換使用的 method,改為使用 cci_connect_ex。並且嘗試加入更多 type 的支援。

      2016-08-05

      Tcl extension for CUBRID database: tclcubrid

      Source code:
      tclcubrid


      About:

      CUBRID is an open source SQL-based relational database management system with object extensions developed by Naver Corporation for web applications.

      tclcubrid is a Tcl extension by using CUBRID CCI (CCI Client Interface) driver to connect CUBRID. I write this extension to research CUBRID and CCI (CCI Client Interface) driver.


      這是開發中的早期版本,而且沒有進行比較完整的測試,比較簡單的功能已經可以使用,但是 BLOB/CLOB 我不知道怎麼樣簡化會比較好,所以目前並不支援。

      使用 CUBRID 10.0 在 openSUSE LEAP 42.1 上測試。


      2016/08/06
      加入實驗性質的 CLOB/BLOB 支援,大小限制為 65536

      2016/08/07
      加入 TDBC interface

      2016/08/10
      移除 bit/varbit 的支援,改寫法以後,結果還是一樣不正確。
      所以我移除掉 bit/varbit 的支援。

      更新 CLOB/BLOB 大小限制為 131072。

      2016/08/11
      更新 bind 所使用的 type 名稱,讓使用的名稱與 TDBC 更接近。
      int -> integer
      short -> smallint

      我知道我在哪裡犯錯了,重新加回 bit/varbit 的支援。

      2016/08/12
      Github 上建立第一個 tag,版本號碼為 0.1。

      2016-07-12

      Build Casstcl on openSUSE LEAP 42.1 (64bit)

      下載 Cassandra C++ driver source code 以後,在解壓縮的根目錄下,修改 CMakeLists.txt 的內容, 因為要加入 openSUSE 的資料。
          elseif(EXISTS "/etc/redhat-release" OR EXISTS "/etc/fedora-release" OR
                 EXISTS "/etc/slackware-version" OR EXISTS "/etc/gentoo-release" OR
                 EXISTS "/etc/os-release")
            if(CMAKE_SIZEOF_VOID_P EQUAL 8)
              set (CMAKE_INSTALL_LIBDIR "lib64")
            else()
              set (CMAKE_INSTALL_LIBDIR "lib")
            endif()
      

      (* 我有送出一個 pull request 被接受了,所以接下來的版本可能可以不用修改這裡)

      Cassandra C++ driver 需要 libuv-devel 和 Open SSL 有安裝才能正確編譯。

      建立一個 build 的目錄,然後使用下面的命令建立 Makefile (for openSUSE 64bit):
      cmake -DCMAKE_INSTALL_PREFIX=/usr  ..
      

      再來就是 make 與 make install: 
      make
      sudo make install
      

      下面就是測試的 C++ 程式:
      #include <cassandra.h>
      #include <stdio.h>
      
      int main() {
        /* Setup and connect to cluster */
        CassFuture* connect_future = NULL;
        CassCluster* cluster = cass_cluster_new();
        CassSession* session = cass_session_new();
      
        /* Add contact points */
        cass_cluster_set_contact_points(cluster, "127.0.0.1");
      
        /* Provide the cluster object as configuration to connect the session */
        connect_future = cass_session_connect(session, cluster);
      
        if (cass_future_error_code(connect_future) == CASS_OK) {
          CassFuture* close_future = NULL;
      
          /* Build statement and execute query */
          CassStatement* statement
            = cass_statement_new("SELECT keyspace_name "
                                 "FROM system_schema.keyspaces", 0);
      
          CassFuture* result_future = cass_session_execute(session, statement);
      
          if(cass_future_error_code(result_future) == CASS_OK) {
            /* Retrieve result set and iterate over the rows */
            const CassResult* result = cass_future_get_result(result_future);
            CassIterator* rows = cass_iterator_from_result(result);
      
            while(cass_iterator_next(rows)) {
              const CassRow* row = cass_iterator_get_row(rows);
              const CassValue* value = cass_row_get_column_by_name(row, "keyspace_name");
      
              const char* keyspace;
              size_t keyspace_length;
              cass_value_get_string(value, &keyspace, &keyspace_length);
              printf("keyspace_name: '%.*s'\n",
                     (int)keyspace_length, keyspace);
            }
      
            cass_result_free(result);
            cass_iterator_free(rows);
          } else {
            /* Handle error */
            const char* message;
            size_t message_length;
            cass_future_error_message(result_future, &message, &message_length);
            fprintf(stderr, "Unable to run query: '%.*s'\n",
                    (int)message_length, message);
          }
      
          cass_statement_free(statement);
          cass_future_free(result_future);
      
          /* Close the session */
          close_future = cass_session_close(session);
          cass_future_wait(close_future);
          cass_future_free(close_future);
        } else {
          /* Handle error */
          const char* message;
          size_t message_length;
          cass_future_error_message(connect_future, &message, &message_length);
          fprintf(stderr, "Unable to connect: '%.*s'\n",
                  (int)message_length, message);
        }
      
        cass_future_free(connect_future);
        cass_cluster_free(cluster);
        cass_session_free(session);
      
        return 0;
      }
      

      注意,system_schema.keyspaces 在 3.x 之前,需要使用 system.schema_keyspaces 才行 (CASSANDRA-6717)。

      因為 Tcl driver 建立在 CPP driver 之上,所以接下來是在 openSUSE 64bit 環境安裝 Tcl driver。

      下面是 build 的命令:

      autoconf
      ./configure --enable-64bit --libdir=/usr/lib64/tcl
      make
      sudo make install
      

      如果成功的話,就可以使用 casstcl 這個套件來存取 Apache Cassandra。

      下面是一個範例:

      package require casstcl
      
      set cass [::casstcl::connect -host 127.0.0.1 -port 9042]
      $cass select "SELECT keyspace_name FROM system_schema.keyspaces;" row {
        parray row
      }
      $cass delete
      

      目前 casstcl 在 prepared statement 使用 ? 做 parameters binding,需要在第一次使用 exec 前呼叫 reimport_column_type_map,執行的結果才會是正確的(更正:或者是在 create table 之後,因為新增的 table 還沒有對應資料)。

      2016-07-07

      tcljsonnet v0.4

      首頁:
      tcljsonnet


      主要更新:
      將 Jsonnet code base 版本升到 v0.8.9 版。

      2016-06-15

      TkCVS

      TkCVS


      因為需要在 Linux 環境中有一個簡易的 SVN 介面,所以下載 TkCVS 來使用。稍微看了一下,我發現是使用呼叫 svn command line tool 然後讀取結果的方法。

      下面是 source code 的片段:
        set commandline "svn log -g -l 1"
        set ret [catch {eval "exec $commandline"} output]
      

      很有趣的做法。

      2016-05-26

      GeodeREST v0.1: Apache Geode REST Client Library for Tcl

      Hompage


      GeodeREST: Apache Geode REST Client Library for Tcl

      About

      Apache Geode provides a database-like consistency model, reliable transaction processing and a shared-nothing architecture to maintain very low latency performance with high concurrency processing.

      This extension is an Apache Geode REST Client Library for Tcl. The library consists of a single Tcl Module file.

      一些說明

      目前有二個方式可以從 Tcl 存取 Apache Geode,一個是利用 memcached interface (memcached-for-Tcl),一個則是 REST interface。

      這個 Tcl extension 試著利用 Apache Geode REST interface 存取資料。

      2016-05-10

      tcl-lmdb v0.3.5

      檔案放置網頁


      tcl-lmdb - Tcl interface to the Lightning Memory-Mapped Database

      About


      This is the Lightning Memory-Mapped Database (LMDB) extension for Tcl using the Tcl Extension Architecture (TEA).

      LMDB is a Btree-based database management library with an API similar to BerkeleyDB. The library is thread-aware and supports concurrent read/write access from multiple processes and threads. The DB structure is multi-versioned, and data pages use a copy-on-write strategy, which also provides resistance to corruption and eliminates the need for any recovery procedures. The database is exposed in a memory map, requiring no page cache layer of its own. This extension provides an easy to use interface for accessing LMDB database files from Tcl.

      Main Change

      • Fix overflow of a nearby variable on the stack patch from gahr
      • Chase gcc 4.8 warning patch from gahr
      • env open command: let -fixedmap default to false

      一些說明


      merge 從 gahr 來的修正 patch。

      2016-05-09

      tclxqilla v0.1

      Homepage


      tclxqilla

      About


      XQilla is an XQuery and XPath 2 library and command line utility written in C++, implemented on top of the Xerces-C library. It is made available under the terms of the Apache License v2.

      XQilla's XQC API implements a standard C API for XQuery implementations, defined in collaboration with the Zorba project.

      tclxqilla is a Tcl extension to use XQilla XQC API to execute XQuery expression.
      This extension is using Tcl_LoadFile to load XQilla library.

      一些說明


      對 XQilla 的 XQC API 做的 Tcl extension。我本來是要做某個東西的 prototype,不過後來發現跟我的想像有點差距,所以只做完簡單版的 Tcl extension for XQilla library 以後,就停止我的計畫了。

      說不定有人會需要,所以我把 source code 放上去 Github。

      2016-05-06

      tcl-lmdb v0.3.4

      檔案放置網頁


      tcl-lmdb - Tcl interface to the Lightning Memory-Mapped Database

      About


      This is the Lightning Memory-Mapped Database (LMDB) extension for Tcl using the Tcl Extension Architecture (TEA).

      LMDB is a Btree-based database management library with an API similar to BerkeleyDB. The library is thread-aware and supports concurrent read/write access from multiple processes and threads. The DB structure is multi-versioned, and data pages use a copy-on-write strategy, which also provides resistance to corruption and eliminates the need for any recovery procedures. The database is exposed in a memory map, requiring no page cache layer of its own. This extension provides an easy to use interface for accessing LMDB database files from Tcl.

      Main Change

      • Update LMDB source code
      • UTF-8 character stripped issue patch and test cases from gahr
      • fix-compiler-warnings patch from gahr

      一些說明


      merge 從 gahr 來的修正 patch,以及更新 LMDB 的 source code。

      2016-05-05

      tcl-swift-bridge

      tcl-swift-bridge


      我在 Github 上發現的專案,目前我沒有在使用 Swift language,所以只是做個記錄,也許以後會用到這樣。

      2016-04-24

      TDBCJDBC v0.1.1

      Homepage


      TDBCJDBC

      About


      Tcl DataBase Connectivity JDBC Driver

      一些說明


      使用 tclBlend 來呼叫 JDBC API。我並沒有每一個部份都測試過,只有執行過簡單的例子,用來確定我拿到的 JDBC driver 是可用的。

      更新 2016-04-27:
      增加 H2 database 與 Apache Derby 的簡單範例,這樣比較有名的 Java embedded database 選擇(HSQLDB, H2 and Apache Derby)就都有簡單範例了。

      更新 2016-04-27:
      加入 bigint type 的處理,更新 date, time, timestamp 與 numeric type 的處理方式

      更新 2016-04-28:
      使用 HSQLDB 測試更新後的 BLOB 處理,儲存一張小圖片進去,然後讀出來存成另外一張圖比對。目前看起來是正常工作的。

      更新 2016-04-29:
      binary type 處理加入 PostgreSQL 的 bytea type name 檢查,然後更正了一些我自己發現的小錯誤,並且更新文件。

      更新 2016-05-04:
      加入 CLOB type 的支援,同時更新 type 處理方面的  code。

      2016-04-22

      TDBC-ODBC and Firebird ODBC (update for Firebird 3.0.0)

      測試環境:
      Windows XP
      Firebird 3.0.0
      Firebird ODBC 2.0.4
      Active Tcl 8.6.4.1

      DSN 設定(和之前一樣):
      TDBC-ODBC and Firebird ODBC 

      package require tdbc::odbc
      
      set connStr "DSN=Firebird DSN; UID=danilo; PWD=danilo;"
      tdbc::odbc::connection create db $connStr
      
      set statement [db prepare {create table person (id integer, name varchar(40))}]
      $statement execute
      $statement close
      
      set statement [db prepare {insert into person values(1, 'leo')}]
      $statement execute
      $statement close
      
      set statement [db prepare {insert into person values(2, 'yui')}]
      $statement execute
      $statement close
      
      set statement [db prepare {SELECT * FROM person}]
      
      $statement foreach row {
          puts [dict get $row ID]
          puts [dict get $row NAME]
      }
      
      $statement close
      
      set statement [db prepare {drop table person}]
      $statement execute
      $statement close
      db close
      

      比較好的地方是,最後 drop table 不需要使用第二個 script 執行才行,之前會那樣做是因為如果直接 drop (可能會)有錯誤訊息而無法刪除,但是看起來 Firebird 3.0.0 已經和其它的資料庫行為一致了。

      2016-04-20

      Buiild tclBlend on Windows 7 (64bit)

      使用 MSYS2 和 JDK8,需要更新 tcljava.m4,加入下列的段落:

              # Sun JDK 1.4 and 1.5 for Win32 (server JVM)
      
              F=lib/jvm.lib
              if test "x$ac_java_jvm_jni_lib_flags" = "x" ; then
                  AC_MSG_LOG([Looking for $ac_java_jvm_dir/$F], 1)
                  if test -f $ac_java_jvm_dir/$F ; then
                      # jre/bin/client must contain jvm.dll
                      # jre/bin/server directory could also contain jvm.dll,
                      # just assume the user wants to use the server JVM.
                      DLL=jre/bin/server/jvm.dll
                      if test -f $ac_java_jvm_dir/$DLL ; then
                          AC_MSG_LOG([Found $ac_java_jvm_dir/$F], 1)
                          D1=$ac_java_jvm_dir/jre/bin
                          D2=$ac_java_jvm_dir/jre/bin/server
                          ac_java_jvm_jni_lib_runtime_path="${D1}:${D2}"
                          ac_java_jvm_jni_lib_flags="$ac_java_jvm_dir/$F"
                      fi
                  fi
              fi 
      

      原來的只有 Sun JDK 1.4 and 1.5 for Win32 (client JVM),所以 server JVM 要自己加入。如果執行 autoconf 有困難,可以考慮直接修改 configure,找到 Sun JDK 1.4 and 1.5 for Win32 (client JVM) 的部份,把 jre/bin/client 的 client 改為 server。

      其它的部份都一樣

      2016-04-12

      TDBC: get resultset columns type

      只有在 TDBC::SQLite3 上測試過。目前可以拿到 table columns 的 type 資料,而 resultset 只傳回來 columns name list,利用 table columns 的 type 資料傳回一份對照表。

      proc getColumnsType {COLUMNS TABLE_COLUMNS} {
          puts $COLUMNS
          puts $TABLE_COLUMNS
          set result [dict create]
          foreach column $COLUMNS {
              set column_2 [string tolower $column]
              set res [dict get $TABLE_COLUMNS $column_2]
              set type [dict get $res type]
              dict set result $column $type
          }
          
          return $result
      }
      
      
      set table_columns [db columns mylist]
      
      set statement [db prepare {SELECT * FROM mylist}]
      set resultset [$statement execute]
      set res_columns [$resultset columns]
      
      # test method
      puts [getColumnType $res_columns $table_columns]
      
      $statement close
      


      我想我搞懂問題點在哪裡了。如果我操作超過一個表格,那該怎麼做?

      如果有時間,我寫一份 TDBC 某個 driver 的研究看看 TDBC 的機制,然後再思考看看該怎麼做。

      更新:
      看起來我目前不會有操作超過一個表格要 get column type 的情況,所以我想…… 如果有需要再研究好了。


      更新:

      目前來看,TDBC 實作的策略可以分為二個。

      第一個策略,建立 stubs 以後,運用 Tcl 8.6 Tcl_LoadFile,使用 database API
      第二個策略,使用原有的 Tcl 套件,然後加上一層 TDBC interface

      tdbc::connection

      連線到 database, database tables and table columns, primary key..., etc meta data

      tdbc::statement

      當使用者使用 tdbc::connection prepare 函式,就會建立一個 tdbc::statement 物件。

      建立物件時就會使用 tdbc::tokenize (Tcl code) 或者是 Tdbc_TokenizeSql 找出來使用者變數,然後使用 ? (或者是 SQL 語法接受的)取代使用者變數產生 params (有 type 等資料)並且產生 database 可以接受的 SQL 字串

      但是這並不是 SQL 語法分析,只是找出 : 或者是 $ 開頭的字串。

      tdbc::resultset

      當使用者使用 statement object execute method 或者是其它的 command 會觸發 execute method 時就會建立一個 tdbc::resultset 物件。

      在建立的時候,就會使用 params 的資料與取得使用者所連結的變數,真正的執行並且取得結果。

      So...

      如果真的有需要的話,應該是要更改 resultset 相關的部份,另外還要考慮如果不支援這樣操作的資料庫應該要怎麼做。

      2016-04-10

      TclBlend and JDBC

      使用 MonetDB 的 JDBC Driver 進行測試。

      參考資料:
      [Activetcl] TclBlend - Examples. 

      設定 CLASSPATH:
      set CLASSPATH=c:\monetdb-jdbc-2.19.jar

      #########################################################  
      ## Source packages. 
      #########################################################  
      #
      package require java
      
      #################################################################
      # putsLog with timestamp.
      ####################################################################
      proc putsLog { a } {
      
          set host [ info host ]
      
          set compTime [clock format [clock seconds] -format "%Y-%m-%d-%H.%M.%S"]
      
          puts "\[$host:$compTime\] $a"
      
      }
      #######################################
      ## Proc - jdbcConnect. 
      #######################################
      proc jdbcConnect { className url username password sqlQuery } {
      
         putsLog "proc - [info level 0 ]"
      
         # import required classes 
         java::import java.sql.Connection
         java::import java.sql.DriverManager
         java::import java.sql.ResultSet
         java::import java.sql.SQLWarning
         java::import java.sql.Statement
         java::import java.sql.ResultSetMetaData 
         java::import java.sql.DatabaseMetaData 
      
         # load database driver .
         java::call Class forName $className
      
         putsLog "connection URL is:  $url\n"   
         
         set ConnectionI [ java::call DriverManager getConnection $url $username $password] 
      
         putsLog "transaction isolation level is [ $ConnectionI getTransactionIsolation ]"
      
         putsLog "#########################################"
         putsLog "### Database connection details"
         putsLog "#########################################"
      
         # get the database metadata information.
         #Retrieves a DatabaseMetaData object that contains metadata about the database
         #to which this Connection object represents a connection.
      
         set DatabaseMetaDataI [ $ConnectionI getMetaData ]
      
         putsLog [ $DatabaseMetaDataI getDatabaseProductName ]
         putsLog [ $DatabaseMetaDataI getDatabaseProductVersion ]
         putsLog "database version [ $DatabaseMetaDataI getDatabaseMajorVersion ]\.[ $DatabaseMetaDataI getDatabaseMinorVersion ]"
         putsLog "driver version   [ $DatabaseMetaDataI getDriverName ] [ $DatabaseMetaDataI getDriverMajorVersion ]\.[ $DatabaseMetaDataI getDriverMinorVersion ]"
         putsLog "jdbc version     [ $DatabaseMetaDataI getJDBCMajorVersion  ]\.[ $DatabaseMetaDataI getJDBCMinorVersion  ]"
         putsLog "connect username [ $DatabaseMetaDataI getUserName ]"
         putsLog "transaction isolation level is [ $ConnectionI getTransactionIsolation ] \n"
      
         # get a list of table names in database.
         # if there are no tables the results set is empty.  
      
         set opt1 [java::field ResultSet TYPE_SCROLL_INSENSITIVE]
         set ResultSetI [ $DatabaseMetaDataI getCatalogs ]
         set ResultSetMetaDataI [ $ResultSetI getMetaData ] 
         set columnCount        [ $ResultSetMetaDataI getColumnCount ]
      
         puts "Create query\n" 
      
         set opt1 [java::field ResultSet TYPE_SCROLL_INSENSITIVE]
         set opt2 [java::field ResultSet CONCUR_READ_ONLY ]   
         set StatementI [ $ConnectionI createStatement $opt1 $opt2 ]
         
         $StatementI execute $sqlQuery   
         set ResultSetI         [ $StatementI getResultSet ]  
      
         puts "get a list of return columns\n" 
         set ResultSetMetaDataI [ $ResultSetI getMetaData ]  
         set columnCount        [ $ResultSetMetaDataI getColumnCount ]
         set i 1
      
         while { $i <= $columnCount } {
             set columnName [ $ResultSetMetaDataI getColumnName $i ]      
             lappend columnList $columnName
             incr i 
         }    
      
         unset i
         puts "loop over the results set and print column name, column value.\n" 
      
         while { [ $ResultSetI next ] == 1 } {
            foreach i $columnList {
                puts [ format "%-5s %-30s %-s" " " "$i" "[ $ResultSetI getString $i ]" ]
            } 
      
             puts [ format "\n%-5s \n" [ string repeat "#" 50] ]
         }    
      
         puts "Close Connections\n" 
      
        
         $ResultSetI  close 
         $ConnectionI close
      
      }
      ######################################
      # Main Control.
      ######################################
      
      putsLog "executing [info script]"
      
      # make script drive independent.
      
      set drive [lindex [file split [info nameofexecutable]] 0 ] 
      set reportFile   C:\\reports\\oracleConnect.txt
      set reportFileId [ open $reportFile w ] 
      
      set className    {nl.cwi.monetdb.jdbc.MonetDriver}
      set url          jdbc:monetdb://localhost:50000/demo   
      set username     monetdb
      set password     monetdb
      
      set sqlQuery "SELECT id, name FROM tables"  
      
      jdbcConnect $className $url $username $password $sqlQuery
      


      使用 HSQLDB 的 JDBC Driver 進行測試。

      設定 CLASSPATH:
      set CLASSPATH=c:\hsqldb.jar

      
      #########################################################  
      ## Source packages. 
      #########################################################  
      #
      package require java
      
      #################################################################
      # putsLog with timestamp.
      ####################################################################
      proc putsLog { a } {
      
          set host [ info host ]
      
          set compTime [clock format [clock seconds] -format "%Y-%m-%d-%H.%M.%S"]
      
          puts "\[$host:$compTime\] $a"
      
      }
      #######################################
      ## Proc - jdbcConnect. 
      #######################################
      proc jdbcConnect { className url username password sqlQuery } {
      
         putsLog "proc - [info level 0 ]"
      
         # import required classes 
         java::import java.sql.Connection
         java::import java.sql.DriverManager
         java::import java.sql.ResultSet
         java::import java.sql.SQLWarning
         java::import java.sql.Statement
         java::import java.sql.ResultSetMetaData 
         java::import java.sql.DatabaseMetaData 
      
         # load database driver .
         java::call Class forName $className
      
         putsLog "connection URL is:  $url\n"   
         
         set ConnectionI [ java::call DriverManager getConnection $url $username $password] 
      
         putsLog "transaction isolation level is [ $ConnectionI getTransactionIsolation ]"
      
         putsLog "#########################################"
         putsLog "### Database connection details"
         putsLog "#########################################"
      
         # get the database metadata information.
         #Retrieves a DatabaseMetaData object that contains metadata about the database
         #to which this Connection object represents a connection.
      
         set DatabaseMetaDataI [ $ConnectionI getMetaData ]
      
         putsLog [ $DatabaseMetaDataI getDatabaseProductName ]
         putsLog [ $DatabaseMetaDataI getDatabaseProductVersion ]
         putsLog "database version [ $DatabaseMetaDataI getDatabaseMajorVersion ]\.[ $DatabaseMetaDataI getDatabaseMinorVersion ]"
         putsLog "driver version   [ $DatabaseMetaDataI getDriverName ] [ $DatabaseMetaDataI getDriverMajorVersion ]\.[ $DatabaseMetaDataI getDriverMinorVersion ]"
         putsLog "jdbc version     [ $DatabaseMetaDataI getJDBCMajorVersion  ]\.[ $DatabaseMetaDataI getJDBCMinorVersion  ]"
         putsLog "connect username [ $DatabaseMetaDataI getUserName ]"
         putsLog "transaction isolation level is [ $ConnectionI getTransactionIsolation ] \n"
      
         # get a list of table names in database.
         # if there are no tables the results set is empty.  
      
         set opt1 [java::field ResultSet TYPE_SCROLL_INSENSITIVE]
         set ResultSetI [ $DatabaseMetaDataI getCatalogs ]
         set ResultSetMetaDataI [ $ResultSetI getMetaData ] 
         set columnCount        [ $ResultSetMetaDataI getColumnCount ]
      
         puts "Create query\n" 
      
         set opt1 [java::field ResultSet TYPE_SCROLL_INSENSITIVE]
         set opt2 [java::field ResultSet CONCUR_READ_ONLY ]   
         set StatementI [ $ConnectionI createStatement $opt1 $opt2 ]
         
         $StatementI execute $sqlQuery   
         set ResultSetI         [ $StatementI getResultSet ]  
      
         puts "get a list of return columns\n" 
         set ResultSetMetaDataI [ $ResultSetI getMetaData ]  
         set columnCount        [ $ResultSetMetaDataI getColumnCount ]
         set i 1
      
         while { $i <= $columnCount } {
             set columnName [ $ResultSetMetaDataI getColumnName $i ]      
             lappend columnList $columnName
             incr i 
         }    
      
         unset i
         puts "loop over the results set and print column name, column value.\n" 
      
         while { [ $ResultSetI next ] == 1 } {
            foreach i $columnList {
                puts [ format "%-5s %-30s %-s" " " "$i" "[ $ResultSetI getString $i ]" ]
            } 
      
             puts [ format "\n%-5s \n" [ string repeat "#" 50] ]
         }    
      
         puts "Close Connections\n" 
      
        
         $ResultSetI  close 
         $ConnectionI close
      
      }
      ######################################
      # Main Control.
      ######################################
      
      putsLog "executing [info script]"
      
      # make script drive independent.
      
      set drive [lindex [file split [info nameofexecutable]] 0 ] 
      set reportFile   C:\\reports\\oracleConnect.txt
      set reportFileId [ open $reportFile w ] 
      
      set className    {org.hsqldb.jdbc.JDBCDriver}
      set url          jdbc:hsqldb:file:testdb 
      set username     SA
      set password     ""
      
      set sqlQuery "SELECT * FROM INFORMATION_SCHEMA.TABLES"  
      
      jdbcConnect $className $url $username $password $sqlQuery
      

      請參考上一篇文章(再加上上一次 Build TclBlend 的文章),二個都進行 patch 以後,在 8.6.5 看起來還不錯,至少可以正確的執行 MonetDB 與 HSQLDB JDBC driver。

      TclBlend: Tcl core patch

      Info from Tcler's wiki


      在之前我把範圍縮小到 8.6.0 到 8.6.1 以後,就不知道要怎麼樣才能夠修正,不過有人找到 root cause 了。

      Within the function "Tcl_GetCommandFromObj", change
      from:
          if (SetCmdNameFromAny(interp, objPtr) != TCL_OK) {
              return NULL;
          }
      to:
       if (tclCmdNameType.setFromAnyProc(interp, objPtr) != TCL_OK) {
              return NULL;
          }
      

      經過檢查 8.6.5,確定之前的小測試程式不會當機。如果 Tcl core 會接納這個 patch,那麼至少 Tcl core 這邊造成的當機因素就消失了。

      2016-04-07

      Fix SVN "Failed to run the WC DB work queue" problem

      svn failed to run the wc db work queue associated with file (windows symbol ? issue)

      如果使用 SQLite3 的 command line tool,
      cd {work-dir-base}
      sqlite3 .svn/wc.db "delete from work_queue"
      

      因為我有裝 TDBC-SQLite3,所以就沒有下載 SQLite3 的 command line tool,直接使用 TDBC 來解決問題,下面是大概的樣子:
      #!/usr/bin/tclsh
      package require tdbc::sqlite3
      
      # Fix SVN "Failed to run the WC DB work queue" problem
      tdbc::sqlite3::connection create db "d:/android/.svn/wc.db" 
      
      set statement [db prepare {delete from work_queue}]
      $statement execute
      $statement close
      
      db close
      

      這是在 Android 6.0.x code base 上發生的,原因請參閱 Forbidden file and folder names on Windows

      The following are reserved names, which cannot be assigned to a folder or file (normally):
      • CON
      • PRN
      • AUX
      • CLOCK$ (NT and older)
      • NUL
      • COM1
      • COM2
      • COM3
      • COM4
      • COM5
      • COM6
      • COM7
      • COM8
      • COM9
      • LPT1
      • LPT2
      • LPT3
      • LPT4
      • LPT5
      • LPT6
      • LPT7
      • LPT8
      • LPT9
      而我發現,有一個 kernel 下的檔案叫做 aux.c,所以在 Windows 平台下視為不正常的檔名。解決的方法是先建立與刪除檔案,再 svn update 或者是 svn cleanup。

      建立檔案:
      echo "" >  \\.\d:\android\kernel\drivers\gpu\drm\nouveau\core\subdev\i2c\aux.c
      

      刪除檔案:
      del \\.\d:\android\kernel\drivers\gpu\drm\nouveau\core\subdev\i2c\aux.c
      

      更新: android\external\libunwind 下有一個 aux 目錄,我發覺 Windows 會非常直接的擋下來,所以我想要在 Windows 平台上看 Android 6.0.x 的 source code 將成為困難的任務,除非 Windows 修改檢查檔名的規則,不然就…… 放生吧。

      tcljsonnet v0.3

      首頁:
      tcljsonnet


      主要更新:
      將 Jsonnet code base 版本升到 v0.8.8 版。

      2016-03-22

      tcljsonnet v0.2

      首頁:
      tcljsonnet


      主要更新:
      將 Jsonnet code base 版本升到 v0.8.7 版。

      2016-03-21

      Add https support to HBaseClient-Tcl

      HBaseClient-Tcl


      可以參考的連結:
      https://s3.amazonaws.com/dev.hortonworks.com/HDPDocuments/HDP2/HDP-2.1.2/bk_reference/content/ch05s08.html

      首先是產生 keystore:
      keytool -genkey -alias hbase -keyalg RSA -keysize 1024 -keystore hbase.jks

      再來是 conf/hbase-site.xml,加入下列的設定:

      <property>
          <name>hbase.rest.ssl.enabled</name>
          <value>true</value>
      </property>
      
      <property>
          <name>hbase.rest.ssl.keystore.store</name>
          <value>/path/to/keystore</value>
      </property>
      
      <property>
          <name>hbase.rest.ssl.keystore.password</name>
          <value>keystore password</value>
      </property>
      
      <property>
          <name>hbase.rest.ssl.keystore.keypassword</name>
          <value>key password</value>
      </property>
      

      第一項就是開啟 ssl 的支援,第二項就是設定  hbase.jks 的位置,例如如果我是在 /home/danilo/Programs/hbase-1.1.3 中,那麼就要填 /home/danilo/Programs/hbase-1.1.3/hbase.jks。

      第三項和第四項就是在建立的過程所填寫的密碼。

      如果設定成功,就可以使用 https 連線。

      使用 https 來連線,所以我就需要改寫  HBaseClient-Tcl 來測試,基本上就是從上一篇 DrillREST  的實作來的:

              if {$ssl_enabled} {
                  if {[catch {package require tls}]==0} {
                      http::register https 443 [list ::tls::socket -ssl3 0 -ssl2 0 -tls1 1]
                  } else {
                      error "SSL_ENABLED needs package tls..."
                  }
              }
      

      經過測試,看起來可以使用。

      2016-03-15

      Add https support to DrillREST

      Configuring Web Console and REST API Security 中有提到,

      Drill 1.2 uses code-level support for transport layer security (TLS) to secure the Web Console and REST API. By default, the Web Console and REST API support the HTTP protocol. You set the following start-up option to TRUE to enable HTTPS support:

      drill.exec.http.ssl_enabled

      By default this start-up option is set to FALSE.

      Drill generates a self-signed certificate that works with SSL for HTTPS access to the Web Console.

      如果使用瀏覽器去連 Web Console,是會有警告的。

      我不太確定我是不是有完全做對,但是 Apache Drill 的 SSL_ENABLED 在設定打開以後,使用 tls 套件去連線是可以正確連線的。

          constructor {{SERVER http://localhost:8047} {SSL_ENABLED 0}} {
               set server $SERVER
              set ssl_enabled $SSL_ENABLED
      
              if {$ssl_enabled} {
                  if {[catch {package require tls}]==0} {
                      http::register https 443 [list ::tls::socket -ssl3 0 -ssl2 0 -tls1 1]
                  } else {
                      error "SSL_ENABLED needs package tls..."
                  }
              }
           }
      

      重點是 package require tls 和下面一行的設定,就完成了。

      2016-03-11

      DrillREST v0.1

      DrillREST:Apache Drill REST Client Library for Tcl


      Apache Drill 是一個查詢引擎(可以是分散式系統,或者是跑 embedded mode 單機執行),可以用來查詢有 storage plugin 的資料源(包含 Hadoo/HBase, MongoDB, csv 檔案,JSON 檔案和 Parquet 格式的檔案)。

      這是一層 SQL layer,讓你用 SQL-2003 語法(Apache Drill 官網還特別強調自己是標準的 SQL,不是 SQL-like)查詢有支援的資料源。

      目前還有一個小缺陷,就是沒有正式支援 Apache Cassandra,但是網路上已經有人可以 patch 以後使用 Apache Drill 查詢 Cassandra,所以我想如果真的有需要,會有人做出來的。

      Apache Drill 友善的地方是有 JDBC/ODBC 介面,所以如果要使用 ODBC 來連,可以使用 Tcl 的 TDBC-ODBC 或者是使用其它的 ODBC extension,就可以使用 Apache Drill來查詢各式各樣的資料源(只要 Apache Drill 有支援)。

      然後 DrillREST 就如同套件的名稱,使用 Apache Drill REST interface 進行查詢的工作。

      如果以查詢資料然後進行分析來講,Apache Drill 是一個強力工具,但是不知道對比 Apache Spark 的戰力如何。

      2016-03-09

      HBaseClient-Tcl v0.1

      HBaseClient-Tcl: HBase REST Client Library for Tcl


      要連接 HBase 目前有三個方式(我所知道的):
      • Java API
      • Thrift interface
      • REST interface
      這個是閱讀相關的 REST interface 文件以後寫出來的套件,只是確定 Apache HBase REST interface 可以使用,並且我知道該怎麼寫的寫出來記錄而已。

      一開始我本來打算用 Thrift + C++ + Tcl sample extension 實作一個 prototype,但是我很快就發現 Thrift 的難度比一開始想像的還要高,嗯…… 然後接下來我就發現 HBase 有提供 REST 介面,所以就實驗看看這個介面能不能使用,至於 Thrift 就跟他說再見吧。

      2016-03-04

      Tclunqlite v0.2.7

      檔案放置網頁


      Tclunqlite

      About


      This is the UnQLite extension for Tcl using the Tcl Extension Architecture (TEA).

      UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL (Key/Value store and Document-store) database engine. This extension provides an easy to use interface for accessing UnQLite database files from Tcl.

      Main Change

      1. Fix CURSOR getkey potential issue
      2. Add related test cases
      3. Add Tcl_GetIntFromObj() error check


      說明


      這是一個小更新的版本,加入更多的 option 檢查。

      2016-03-03

      tcl.snappy v0.1

      tcl.snappy

      Snappy is a compression/decompression library. It does not aim for maximum compression, or compatibility with any other compression library; instead, it aims for very high speeds and reasonable compression.

      This extension is a Tcl extension for snappy library.


      我很快樂的寫完以後,才發現在很久很久以前就有人寫好了類似的套件(雖然我是用更霸道的方式,直接放 Snappy library 的 source code 一起編譯)。不過畢竟花了時間,所以還是放上去我的網站跟 Github 了。

      2016-03-01

      eXist-db SOAP and Web Services for Tcl

      使用 Web Services for Tcl 來連線 eXist-db 和斷線。eXist-db 有支援 REST 和 SOAP,這裡嘗試使用 eXist-db 提供的 SOAP介面

      package require WS::Client
      # package require dict
      
      ::WS::Client::GetAndParseWsdl "http://localhost:8080/exist/services/Query?WSDL"
      
      # Connect to eXist-db
      dict set args userId "guest"
      dict set args password "guest"
      
      set result [::WS::Client::DoCall QueryService connect $args]
      set sessionId [dict get $result connectReturn]
      
      # Disconnect
      dict set args sessionId $sessionId
      set result [::WS::Client::DoCall QueryService disconnect $args]
      


      http://localhost:8080/exist/services/Query?WSDL 就是所有提供的 function。

      PS. eXist-db 3.0 RC1 移除了 SOAP 的支援,不過 2.2 的還可以用。

      2016-02-25

      tcl-lmdb v0.3.3

      檔案放置網頁


      tcl-lmdb - Tcl interface to the Lightning Memory-Mapped Database

      About


      This is the Lightning Memory-Mapped Database (LMDB) extension for Tcl using the Tcl Extension Architecture (TEA).

      LMDB is a Btree-based database management library with an API similar to BerkeleyDB. The library is thread-aware and supports concurrent read/write access from multiple processes and threads. The DB structure is multi-versioned, and data pages use a copy-on-write strategy, which also provides resistance to corruption and eliminates the need for any recovery procedures. The database is exposed in a memory map, requiring no page cache layer of its own. This extension provides an easy to use interface for accessing LMDB database files from Tcl.

      Main Change

      • Update README.md
      • Improve dbi_handle drop command behavior when del_flag equals 1. If del_flag equals 1, delete dbi_handle command.
      • Add more check in env_handle open -mode option
      • Improve dbi_handle drop command option check
      • Improve dbi_handle del command option check

      一些說明


      這是一個小更新的版本,增加了一些 command option 的檢查。然後 dbi_handle drop 的行為有一點改變,當 del_flag 設為 1,會將 dbi_handle command 也一起刪除。

      2016-02-23

      Building Tcl/Tk with MSYS2 (for x86_64)

      下載並且安裝 MSYS2 以後,首先先更新 MSYS2 的核心套件:

      pacman -Sy
      pacman --needed -S bash pacman pacman-mirrors msys2-runtime
      

      然後離開 MSYS2-shell 再重啟,並且在安裝其它的套件之前使用下面的命令:

      pacman -Su
      

      離開 MSYS2-shell 再重啟,就有一個基本可用的 MSYS2-shell。

      安裝必要的套件:

      pacman -S base-devel mingw-w64-x86_64-toolchain

      如果要一起裝 (i686 and x86_64),使用下面的:

      pacman -S base-devel mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain

      到這裡就安裝完需要的檔案。然後把 Tcl 8.6.4 的 source code 放在 /src/tcl,Tk 8.6.4 的 source code 放在 /src/tk,使用下面的 script 來編譯:

      #!/bin/sh
      mkdir -p /src
      mkdir -p /opt/tcl
      mkdir -p /build/tcl
      mkdir -p /build/tk
      [ -e /src/tcl ] && {
          cd /build/tcl
          /src/tcl/win/configure --prefix=/opt/tcl --enable-64bit --enable-threads && make && make install && {
              [ -e /src/tk ] && {
              cd /build/tk
              /src/tk/win/configure --prefix=/opt/tcl --enable-threads --with-tcl=/build/tcl \
                  && make && make install
              }
          }
      }
      

      如果是使用 MSYS2 在 Windows 平台上編譯 64 位元的 Tcl/Tk,要加 --enable-64bit,不然會在 zlib 連結的時候失敗。

      tclConfig.sh and Ubuntu

      最近安裝 Ubuntu 14.04 (for x86_64) 的 VM,所以也安裝了內建的 Tcl/Tk 8.6 來觀察檔案位置。不同的 Linux distribution 讓人困擾的地方就是安裝的地方可能會有一些小差異。目前 Ubuntu 能夠安裝的版本是 8.6.1。

      tclConfig.sh,  tclooConfig.sh  和 tkConfig.sh 被 Ubuntu 使用連結的方式放一份在 /usr/lib,而與 openSUSE 放置 64 位元與 32 位元的方式不同,Ubuntu 的應該是這樣:

      64 位元 -> /usr/lib
      32 位元 -> /usr/lib32

      測試安裝 tcllib 1.18 的結果,預設會安裝在 /usr/lib/tcllib1.18。

      還有一些 pure tcl 的部份放在 /usr/share/tcltk,舉例來說,如果安裝 tdbc::sqlite3,就會有下面的檔案:
      /usr/share/tcltk/tcl8/8.6/tdbc/sqlite3-1.0.0.tm

      2016-02-21

      tcl-lmdb v0.3.2

      檔案放置網頁


      tcl-lmdb - Tcl interface to the Lightning Memory-Mapped Database

      About


      This is the Lightning Memory-Mapped Database (LMDB) extension for Tcl using the Tcl Extension Architecture (TEA).

      LMDB is a Btree-based database management library with an API similar to BerkeleyDB. The library is thread-aware and supports concurrent read/write access from multiple processes and threads. The DB structure is multi-versioned, and data pages use a copy-on-write strategy, which also provides resistance to corruption and eliminates the need for any recovery procedures. The database is exposed in a memory map, requiring no page cache layer of its own. This extension provides an easy to use interface for accessing LMDB database files from Tcl.

      Main Change

      • Update source code to LMDB 0.9.70 with extra fixes from github. ITS#7992 Fix memleak in prev change (on Windows platform)
      • Update README.md
      • CURSOR get command add options: -get_multiple and -next_multiple
      • Fix CURSOR del command option issue. Give -nodupdata correct option check
      • env_handle set_mapsize/set_maxreaders/set_maxdbs/sync command option add more check

      一些說明


      這是一個小更新的版本,增加了一些 command option 的檢查。

      再來是重新加入 tests 目錄到 source code,並且加進最基本的 test cases。 

      2016-02-20

      Tclunqlite v0.2.6

      檔案放置網頁


      Tclunqlite

      About


      This is the UnQLite extension for Tcl using the Tcl Extension Architecture (TEA).

      UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL (Key/Value store and Document-store) database engine. This extension provides an easy to use interface for accessing UnQLite database files from Tcl.

      Main Change

      1. Update README.md
      2. Update DBNAME config command Tcl_WrongNumArgs string
      3. Replace Tcl_GetString to Tcl_GetStringFromObj


      說明


      這是一個小更新的版本,把 DBNAME config 的錯誤提示文字改成比較正確的版本,並且把Tcl_GetString 更換為使用 Tcl_GetStringFromObj。

      再來是重新加入 tests 目錄到 source code,並且加進最基本的 test cases。

      2016-02-19

      Parse simple XML data

      <?xml version="1.0" encoding="UTF-8"?>
      <file expr="files_152f8d105f3" name="Test.pptx" oid="123456"
        size="29651" vault="MainVault" version="1.5.1"/>
      

      用 tDom 拿資料:

      package require tdom
      
      set xmldata {<?xml version="1.0" encoding="UTF-8"?>
      <file expr="files_152f8d105f3" name="Test.pptx" oid="123456"
        size="29651" vault="MainVault" version="1.5.1"/>}
      
      set doc [dom parse $xmldata]
      set root [$doc documentElement]
      set expr [$root getAttribute expr]
      set name [$root getAttribute name]
      set oid [$root getAttribute oid]
      set size [$root getAttribute size]
      set vault [$root getAttribute vault]
      set version [$root getAttribute version]
      

      不知道有沒有更簡短的寫法,看到 comp.lang.tcl 有人問自己做的練習。


      PS:
      如果不知道 attributes,要先取得列表,可以使用:

      set attrs [$root attributes]
      

      2016-02-04

      Tcllib 1.18

      ANNOUNCE: Tcllib 1.18 (comp.lang.tcl)


      Overview
      ========
      18 new packages in 14 modules
      32 changed packages in 22 modules
      24 internally changed packages in 18 modules
      357 unchanged packages in 97 modules
      438 packages, total in 126 modules, total


      所以 Tcllib 釋出了 1.18 版。

      2016-02-03

      Tcltaglib v0.5 and Tclqrencode v0.3

      主要的 code 都沒變,只是進版了。

      Tcltaglib

      • Use Tcl_TranslateFileName() to handle filename

      這樣檔名就可以不用寫絕對路徑,而可以處理像是 ~  開頭的路徑方式。這樣子在使用上會比較方便,所以版本被我進版成為 v0.5。


      Tclqrencode 

      這次稍微整合 libqrencode 的一些 source code 上的新增說明,然後更新以後版本被我進版成為 v0.3。

      (* 其實和 v0.2 一樣,只是 libqrencode source code 一些地方多加空白和說明)

      因為 Tclqrencode 連結到 libpng,理論上是有被影響到(因為我還在網頁上放了 libpng 的相關檔案)。然而我困惑的地方是如果像 libpng 這樣發出 Vulnerability Warning 公告的時候,我到底該怎麼處理才是比較好的處理方式?

      2016-02-02

      Detecting the Tcl implementation in use

      Tcler' wiki: Detecting the Tcl implementation in use

      參考連結:
      TIP #440: Add engine to tcl_platform Array


      在 Tcler's wiki 尋找資料時看到的,我覺得很有趣,所以記錄一下。

      2016-01-31

      tcl-lmdb v0.3.1

      檔案放置網頁


      tcl-lmdb - Tcl interface to the Lightning Memory-Mapped Database

      About


      This is the Lightning Memory-Mapped Database (LMDB) extension for Tcl using the Tcl Extension Architecture (TEA).

      LMDB is a Btree-based database management library with an API similar to BerkeleyDB. The library is thread-aware and supports concurrent read/write access from multiple processes and threads. The DB structure is multi-versioned, and data pages use a copy-on-write strategy, which also provides resistance to corruption and eliminates the need for any recovery procedures. The database is exposed in a memory map, requiring no page cache layer of its own. This extension provides an easy to use interface for accessing LMDB database files from Tcl.

      Main Change

      • Update source code to LMDB 0.9.70 with extra fixes from github.
      • lmdb open command add option: -dupfixed
      • Update README.md

      一些說明


      多增加一個 lmdb open command 的選項 -dupfixed,以及更新附帶 LMDB 的 source code。

      2016-01-30

      Convert Feedly.opml to MonetDB database

      這只是用來測試我最近寫的 tclmonetdb extension。

      首先是讀出資料,然後寫入 MonetDB database 的 mylist table:

      #!/usr/bin/tclsh
      package require tdom
      package require monetdb
      
      monetdb db -host localhost -port 50000 -user monetdb -passwd monetdb -dbname demo
      
      # MonetDB does not support drop table if exists syntax, use the alternative method
      set stmt [db query "select name from tables where name = 'mylist'"]
      set count [$stmt get_row_count]
      $stmt close
      if {$count > 0} {
          set stmt [db query "drop table mylist"]
          $stmt close
      }
      
      set stmt [db query {create table mylist (title TEXT, xmlUrl TEXT, \
                htmlUrl TEXT, PRIMARY KEY (title))}]
      $stmt close
      
      # setup feedly opml file path
      set filename "c:/feedly.opml"
      # parse XML data
      set doc [dom parse [tDOM::xmlReadFile $filename "UTF-8"]]
      set root [$doc documentElement]
      set nodeList [$root selectNodes /opml/body/outline/outline]
      
      set title ""
      set xmlUrl ""
      set htmlUrl ""
      
      foreach node $nodeList { 
          if {[catch {set title [$node getAttribute title]}] != 0} {
              set title ""
          }
          
          if {[catch {set xmlUrl [$node getAttribute xmlUrl]}] != 0} {
              set xmlUrl ""
          }
          
          if {[catch {set htmlUrl [$node getAttribute htmlUrl]}] != 0} {
              set htmlUrl ""
          }    
          
          set sql_string "insert into mylist values('$title', '$xmlUrl', '$htmlUrl')"    
          set stmt [db query $sql_string]
          $stmt close
      }
      
      db close
      

      再來是讀出來,確定我們有正確寫入:

      #!/usr/bin/tclsh
      package require monetdb
      
      monetdb db -host localhost -port 50000 -user monetdb -passwd monetdb -dbname demo
      
      set stmt [db query {SELECT * FROM mylist}]
      
      set count [$stmt get_row_count]
      for {set i 0} { $i < $count} {incr i 1} {
          set mydict [$stmt fetch_row_dict]
          puts "RSS title: [dict get $mydict title]"
          puts "RSS xmlUrl:  [dict get $mydict xmlurl]"
          puts "RSS htmlUrl:  [dict get $mydict htmlurl]"    
      }
      
      $stmt close
      db close
      

      在 tclmonetdb v0.6 版 redesign 了 API,所以更新這裡的 code。

      2016-01-21

      TDBC-ODBC 與 MonetDB ODBC driver

      測試版本:MonetDB Jul 2015-SP2


      建立新的資料庫的方法:修改 M5server.bat

      rem prepare the arguments to mserver5 to tell it where to put the dbfarm
      
      if "%APPDATA%" == "" goto usevar
      rem if the APPDATA variable does exist, put the database there
      set MONETDBDIR=%APPDATA%\MonetDB5
      set MONETDBFARM="--dbpath=%MONETDBDIR%\dbfarm\danilo"
      

      而後建立新的 ODBC DSN:


      接下來就是測試的 Tcl script:

      package require tdbc::odbc
      
      set connStr "DSN=MonetDB DSN; UID=monetdb; PWD=monetdb;"
      tdbc::odbc::connection create db $connStr
      
      set statement [db prepare {create table person (id integer, name varchar(40))}]
      $statement execute
      $statement close
      
      set statement [db prepare {insert into person values(1, 'leo')}]
      $statement execute
      $statement close
      
      set statement [db prepare {insert into person values(2, 'yui')}]
      $statement execute
      $statement close
      
      set statement [db prepare {SELECT * FROM person}]
      
      $statement foreach row {
          puts [dict get $row id]
          puts [dict get $row name]
      }
      
      $statement close
      
      set statement [db prepare {drop table person}]
      $statement execute
      $statement close
      
      db close
      

      2016-01-18

      The site is back

      Danilo Chang's Home Page


      今天測試,發現可以改回來,所以回復原來的位址了。

      我也同步更新了訊息在 comp.lang.tcl 上。

      2016-01-12

      總之,被我弄到掛掉了

      Danilo Chang's Home Page


      受到 Google Sites 的影響,我目前無法編輯 tcl-lmdb 網頁,原因不明。我在實驗的過程中沒注意到 Google Sites 的刪除與複製網站功能有次數限制, 所以目前無法還原,就先目前這個網頁吧,如果可以改回來我再還原。


      我在 comp.lang.tcl 也發了一篇文章 (Tcl-lmdb v0.3, Tclunqlite and Tcljsonnet),所以暫時就這樣了。


      PS.
      基本上我還是很介意,因為一個 Google Sites 的網站管理者無法編輯修改自己的網頁是一件很瞎的事情,到底是哪裡出問題了?

      PS.
      原來的 tcl-lmdb 無法修改內容,只能夠使用附件管理的方式來增加與刪除附件。 經過思考,我找到了一個解法。首先建立一個 test 網頁,而後將舊的 tcl-lmdb 網頁放在 test 網頁下,複製內容到新的 tcl-lmdb 網頁,於是就可以有一個可以修改的 tcl-lmdb 網頁。 我不確定這是不是 Google Sites 的 bug,但是看來 Google 的雲端服務可能沒那麼可靠。

      不過我已經在 Github 也放了相關的 source code 內容,接下來如果 domain name 可以恢復,應該就可以解決這件事情了,只是日常使用就會遇到使用障礙,如果連 Google 都是如此,我會對整個雲端產業抱持著質疑的態度。

      2016-01-11

      Convert Feedly.opml to SQLite3 database

      目標是把 export 出來的 feedly.opml 檔案的資料放到 SQLite3 database 檔案。我寫完以後,才覺得…… 我好像多此一舉了。

      #!/usr/bin/tclsh
      package require tdom
      package require tdbc::sqlite3
      
      # prepare our sqlite database
      tdbc::sqlite3::connection create db "feedly.db" 
      
      set statement [db prepare {drop table if exists mylist}]
      $statement execute
      $statement close
      
      set statement [db prepare {create table mylist (title TEXT, xmlUrl TEXT, htmlUrl TEXT, PRIMARY KEY (title))}]
      $statement execute
      $statement close
      
      # setup feedly opml file path
      set filename "/home/danilo/Personal/feedly.opml"
      # parse XML data
      set doc [dom parse [tDOM::xmlReadFile $filename "UTF-8"]]
      set root [$doc documentElement]
      set nodeList [$root selectNodes /opml/body/outline/outline]
      
      set title ""
      set xmlUrl ""
      set htmlUrl ""
      set statement [db prepare {insert into mylist values(:title, :xmlUrl, :htmlUrl)}]
      
      foreach node $nodeList { 
          if {[catch {set title [$node getAttribute title]}] != 0} {
              set title ""
          }
          
          if {[catch {set xmlUrl [$node getAttribute xmlUrl]}] != 0} {
              set xmlUrl ""
          }
          
          if {[catch {set htmlUrl [$node getAttribute htmlUrl]}] != 0} {
              set htmlUrl ""
          }    
          
          $statement execute    
      }
      
      $statement close
      db close
      

      第二個則是讀出來確定有轉存成功:

      #!/usr/bin/tclsh
      package require tdbc::sqlite3
      
      tdbc::sqlite3::connection create db "feedly.db" 
      
      set statement [db prepare {SELECT * FROM mylist}]
      
      $statement foreach row {
          puts "RSS title: [dict get $row title]"
          puts "RSS xmlUrl:  [dict get $row xmlUrl]"
          puts "RSS htmlUrl:  [dict get $row htmlUrl]"
      }
      
      $statement close
      db close
      

      2016-01-08

      SQLite 與 PostgreSQL 釋出新版本

      昨天我發現 SQLite 釋出了新的版本,3.10.0,所以已經下載了新的版本並且 build 出來使用簡單的 Tcl Script 測試。

      然後接下來我就發現 PostgreSQL 也釋出了新版,9.5.0 版。我下載並且安裝以後,也使用一些簡單的 Tcl Script 進行測試,接下來需要閱讀文件來對 PostgreSQL 改版的項目進行更多的理解。

      也就是新年一開始,open source relational database 三巨頭中的二個就釋出新版本了,很有趣的發展。

      2016-01-02

      Update couchdbtcl and solr4tcl

      couchdbtcl -

      在寫 solr4tcl 的時候,我才注意到,我沒有在 couchdbtcl 中處理 http::geturl 連線失敗的情況(其實也只是加 catch,避免直接吐出來錯誤訊息),所以加進來處理的部份。


      solr4tcl -

      在進行更多測試的時候,我發現 ping method 雖然拿到 ok,但是我填的 URL 不是正確的,所以更新了 URL。然後 ping method 的 method 是 HEAD,看起來不用設定什麼 Accept header,我也更正了這部份。