イントレ
  • 新規
  • ペイント
  • 一覧
  • 管理
  • Home
  • ダウンロード
  • 日記
  • イラスト
  • リンク
  • About
  •  RSS

本文へジャンプ


イントレ。

« Prev | Today | Next »

SQLiteのユーザー定義関数。

[日記] C# / SQLite >> 2010/01/19 (火) | 07:04:43 | 魅椥 愁
ユーザー定義関数がかなり有用な予感。
SQL文のRandom()とかSum()とかCount()みたいなのを独自に定義出来る。
System.Data.SQLiteを使うと、ユーザー関数をC#側からも定義出きます。

基本的には以下の流れ。
・SQLiteFunctionを継承したクラスを作成し
・SQLiteFunction属性をつける
・SQLiteFunction.RegisterFunction()で登録

呼ぶときはSQL文に普通に記述すればいい。
たとえば、「SELECT * FROM test ORDER BY value COLLATE NETFX_COLLATE」みたいな。


まずはCollation。
ORDER BY ~ COLLATEに使う文字の比較を定義出きます。
オーバーライドするのはCompare()だけでいいみたい。

[SQLiteFunction(Name="NETFX_COLLATE", FuncType=FunctionType.Collation)]
class NETFX_COLLATE : SQLiteFunction
{
public override int Compare(string param1, string param2)
{
return StringComparer.CurrentCulture.Compare(param1, param2);
}
}

Exolorerの文字ソートみたいに数字を考慮するならStrCmpLogicalW()を使ってこんなことも。

[SQLiteFunction(Name="Logical_COLLATE", FuncType=FunctionType.Collation)]
class Logical_COLLATE : SQLiteFunction
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
static extern int StrCmpLogicalW(string str1, string str2);
public override int Compare(string param1, string param2)
{
return StrCmpLogicalW(param1, param2);
}
}


次、Scaler。
Random()とかLower()とかみたいなやつ。
Argumentsには要求する引数の数。-1で可変数にも出来るみたい。
オーバーライドするのはInvoke()メソッド。

[SQLiteFunction(Name="NETFX_RANDOM", FuncType=FunctionType.Scalar, Arguments=0)]
class NETFX_RANDOM : SQLiteFunction
{
readonly static Random rand = new Random();
public override object Invoke(object[] args)
{
return rand.Next();
}
}


最後にAggregate。
Sum()とかCount()みたいに、結果を捜査して出力を返すタイプのもの。
Step()でコンテキストインスタンスを渡して値を保持しておきます。
Step()が必要回数呼ばれて、最後にFinal()が呼ばれます。

[SQLiteFunction(Name = "NETFX_Sum", FuncType = FunctionType.Aggregate, Arguments = 1)]
class NETFX_Sum : SQLiteFunction
{
class Context
{
public decimal Value = 0;
}

public override void Step(object[] args, int stepNumber, ref object contextData)
{
var data = (contextData as Context) ?? (Context)(contextData = new Context());
data.Value += Convert.ToDecimal(args[0]);
}

public override object Final(object contextData)
{
var data = contextData as Context;
return (data == null) ? null : (object)data.Value;
}
}

あーしかしやばいなー。
これは便利すぎる。

Loading...

HTML creation time [0.07sec.]
"intre." by MinagiSyu, sense 1999.11.23.
Powered by Nucleus CMS v3.41

Utilities

タグ
Windows 7 | ツクールもどき | C# | 園芸 | SAP1x | .NET | SAPFx | WPF | PCパーツ | サッカー | ...すべてのタグ
カレンダー
<   2010-01   >
日月火水木金土
     12
3456789
10111213141516
17181920212223
24252627282930
31      
最近の更新
    2010-03-10
  • [日記] TortoiseHg 1.0
  • 2010-03-05
  • [日記] サマーウォーズ
  • 2010-03-01
  • [日記] .NET4→.NET3.5のコード互換性とか。
  • 2010-02-21
  • [日記] SubversionからMercurialへ。
  • 2010-02-16
  • [日記] 第4回MMD杯
  • 2010-02-11
  • [日記] VS2010RC一般公開。
  • 2010-02-07
  • [日記] ソニック4・・・だと?!
Adsense