0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

コンピューターシステム株式会社Advent Calendar 2024

Day 1

Go 言語で SQLite の拡張ライブラリを作る

Last updated at Posted at 2024-11-30

Go 言語で SQLite の拡張ライブラリが作れるライブラリを発見したので、さっそく試してみた。

(最後のコミットが 2023 年 8 月になっているのが若干気になる。)

今回は SQLite の標準でサポートされていないキャメルケースに変換する camelCase 関数を実装してみます。
camelCase 関数の実装は xargs というライブラリの ToCamelCase 関数に委譲しました。

手順

WSL(Ubuntu 22.04) で実施。
※ Windows 11 でもできたので、記事の最後に PowerShell での手順も記載しています。

bash
sudo apt update
sudo apt install -y golang-go sqlite3

mkdir sqlite-my-extensions
cd sqlite-my-extensions

go mod init sqlite-my-extensions
go get -u go.riyazali.net/sqlite
go get github.com/huandu/xstrings

curl -OL https://raw.githubusercontent.com/riyaz-ali/sqlite/master/_examples/Makefile

mkdir camelCase
touch camelCase/camelCase.go

ではい、 camelCase.go を実装していきます。
_examples ディレクトリ内に関数の実装例があるので、今回は upper 関数をまねて作りました。

camelCase.go
package main

import (
	"go.riyazali.net/sqlite"
    "github.com/huandu/xstrings"
)

// CamelCase implements a custom CamelCase(...) scalar sql function
type CamelCase struct{}

func (m *CamelCase) Args() int           { return 1 }
func (m *CamelCase) Deterministic() bool { return true }
func (m *CamelCase) Apply(ctx *sqlite.Context, values ...sqlite.Value) {
	ctx.ResultText(xstrings.ToCamelCase(values[0].Text()))
}

func init() {
	sqlite.Register(func(api *sqlite.ExtensionApi) (sqlite.ErrorCode, error) {
		if err := api.CreateFunction("camelCase", &CamelCase{}); err != nil {
			return sqlite.SQLITE_ERROR, err
		}
		return sqlite.SQLITE_OK, nil
	})
}

func main() {}
bash
make
#=> camelCase.so ファイルが作成される。

sqlite3

SQLite で load し、ちゃんと動くかテストします。

SQLite Command Line Shell
.load ./camelCase

.mode table

WITH
  parameterized_tests(word, expected) AS (
    VALUES ('http_server', 'httpServer'),
           ('_camel_case', '_camelCase'),
           ('no_https', 'noHttps'),
           ('_complex__case_', '_complex_Case_'),
           (' complex -case ', ' complex Case '),
           ('all', 'all'),
           ('GOLANG_IS_GREAT', 'golangIsGreat'),
           ('GOLANG', 'golang')
)
SELECT
  word,
  CASE camelCase(word) WHEN expected
    THEN 'Passed' ELSE 'Failed'
  END AS result
  FROM paralized_tests
;

-- +-----------------+--------+
-- |      word       | result |
-- +-----------------+--------+
-- | http_server     | Passed |
-- | _camel_case     | Passed |
-- | no_https        | Passed |
-- | _complex__case_ | Passed |
-- |  complex -case  | Passed |
-- | all             | Passed |
-- | GOLANG_IS_GREAT | Passed |
-- | GOLANG          | Passed |
-- +-----------------+--------+

手軽すぎる。

実装した関数の説明

簡単に実装時に使用した関数の説明を表にしました。
詳しくは、godoc で確認できます。

関数 説明
Args() int 関数が受け取れる引数の数を返します。
Deterministic() bool 同じ引数が与えられた場合、常に同じ値を返すかの真偽値を返します。
Apply(*Context, ...Value) 関数の実際の中身の処理を実装します。単一の値を返す関数は必須です。
sqlite.Register 上記 3 つの関数を実装した構造体とその関数名を登録します。init関数内で実装するので、パッケージの import 時に実行されます。

Windows 版(PowerShell)

go プロジェクトとソースコードの作成手順は割愛。

PowerShell Console
scoop install sqlite3 gcc go
$env:CGO_ENABLED=1

go build -buildmode=c-shared -o camelCase.so sqlite-my-extensions/camelCase
SQLite Command Line Shell
.load camelCase.so

-- 後の確認手順は一緒。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?