Menulis UDFS untuk Embedded Firebird SQL Server
Apa UDFS ?
fungsi User-defined (UDFS) adalah host-bahasa program untuk melaksanakan tugas sering dibutuhkan, melengkapi built-in fungsi SQL seperti MIN () dan MAX (). UDFS adalah ekstensi untuk server Firebird dan melaksanakan sebagai bagian dari proses server. UDFS kata lain dikompilasi fungsi dan terkait dengan perpustakaan-link secara dinamis.
Apa yang Anda butuhkan
Untuk membaca artikel ini secara efektif Anda membutuhkan pengetahuan lanjutan dari C + +, C # dan Firebird SQL. Juga Anda memerlukan memiliki VS 2005 dengan C # dan C + + dipasang untuk membangun sampel. sampel telah memiliki "baterai dalam": semua file yang dibutuhkan untuk Firebird embedded server dan penyedia ADO.NET ditempatkan dalam folder Firebird sampel dan digunakan dalam membangun pasca-acara.
Contoh struktur proyek
\ Firebird. - Folder dengan semua file yang dibutuhkan untuk Firebird Embedded SQL Server
|? \ Meliputi. - Folder dengan *. h file yang dibutuhkan untuk mengkompilasi UDFS
|? \ Lib - folder. Dengan perpustakaan statis diperlukan untuk menghubungkan UDFS
\ MainApp. - Sampel dikelola aplikasi
\ SampleUdf. - UDFS sampel dll
Tentang sampel
Proyek sampel menunjukkan bagaimana untuk mentransfer data biner (BLOB) dari satu tabel menggunakan parser UDFS objek berbasis ke meja lain:
[Kode dari] MainApp. \ \ Batch.sql
CREATE TABLE "RowDataTable" (
"KUNCI Id" INTEGER NOT NULL PRIMARY
"Nilai" blob
)
CREATE TABLE "FSTable" (
"KUNCI Id" INTEGER NOT NULL PRIMARY
, "Nama" VARCHAR (256)
, "FullPath" VARCHAR (256)
, "CreationTime" TIMESTAMP
, "Atribut" INTEGER
, "Ukuran" BIGINT
) Menciptakan UDFS berbasis data biner parser
UDFS Deklarasi
Firebird SQL memiliki sintaks berikut untuk menyatakan UDF:
MENYATAKAN FUNGSI EKSTERNAL nama [datatype | CSTRING (int)
[, Datatype | CSTRING (int) ...]]
RETURNS (datatype [DENGAN NILAI] | CSTRING (int)) [FREE_IT]
RETURNS [] n PARAMETER
ENTRY_POINT 'entryname'
MODULE_NAME 'modulename'; Argumen
Deskripsi
nama
Nama UDF untuk digunakan dalam pernyataan SQL, dapat berbeda dari nama
fungsi tertentu setelah kata kunci ENTRY_POINT
datatype
Datatype dari masukan atau kembali parameter
• Semua parameter masukan diteruskan ke UDF dengan referensi
parameter Kembali • dapat lulus dengan nilai
• Tidak bisa sebuah elemen array
RETURNS
Menentukan nilai kembali dari fungsi. Perhatikan bahwa sintaks tidak memungkinkan untuk menyatakan bahwa tidak ada yang kembali UDF
DENGAN NILAI
Menetapkan bahwa nilai kembali harus dilalui oleh nilai bukan oleh referensi
CSTRING (int)
Menentukan UDF yang mengembalikan string int byte null-diakhiri panjang
FREE_IT
Membebaskan memori dialokasikan untuk nilai kembali setelah selesai menjalankan UDF. Parameter ini harus digunakan dengan alokasi memori ib_util_malloc dalam pelaksanaan fungsi UDF, It's terkandung dalam:
Header: Perpustakaan ib_util.h: DLL ib_util_ms.lib: ib_util.dll RETURNS PARAMETER n
Menentukan bahwa fungsi mengembalikan parameter input ke-n; diperlukan untuk kembali
Gumpalan
'Entryname'
Dikutip string menetapkan nama UDF dalam kode sumber dan disimpan dalam
UDF library
'Modulename'
Dikutip file spesifikasi mengidentifikasi dll yang berisi UDF
Semua dll dengan UDFS harus ditempatkan ke folder UDF di root aplikasi tempat fbembedded.dll disimpan. Ketika permintaan akan deklarasi untuk mesin Firebird eksekusi tidak memerlukan dll UDF untuk ditempatkan dalam folder UDF pada saat itu. Tapi ketika menjalankan beberapa query disimpan prosedur penciptaan yang berisi mesin panggilan UDF diperlukan akan memeriksa fungsi eksternal dalam dll.
Berikut adalah beberapa contoh deklarasi UDF dari proyek sampel:
[Kode dari] MainApp. \ \ Batch.sql
MENYATAKAN FUNGSI EKSTERNAL CreateParser
Blob
RETURNS INTEGER DENGAN NILAI
MODULE_NAME SampleUdf_CreateParser ENTRY_POINT '' 'SampleUdf'
MENYATAKAN FUNGSI EKSTERNAL DestroyParser
INTEGER
RETURNS INTEGER DENGAN NILAI
MODULE_NAME SampleUdf_DestroyParser ENTRY_POINT '' 'SampleUdf'
MENYATAKAN FUNGSI EKSTERNAL GetName
INTEGER
RETURNS CSTRING (256)
MODULE_NAME SampleUdf_GetName ENTRY_POINT '' 'SampleUdf'
MENYATAKAN FUNGSI EKSTERNAL GetCreationTime
INTEGER
RETURNS TIMESTAMP FREE_IT
MODULE_NAME SampleUdf_GetCreationTime ENTRY_POINT '' 'SampleUdf'
MENYATAKAN FUNGSI EKSTERNAL GetSize
INTEGER
RETURNS BIGINT
ENTRY_POINT 'SampleUdf_GetSize' MODULE_NAME 'SampleUdf' UDFS pelaksanaan
Seperti yang Anda tebak, saya menggunakan parameter tipe integer untuk mengirim objek parser yang dibuat dalam tumpukan SampleUdf.dll. Dengan parser segala objek sangat sederhana:
[Kode dari] main.cpp. SampleUdf \ \
kelas SampleParser
(
std:: vector _buffer char ;
size_t _pathLen;
char * _name;
publik:
SampleParser (std:: vector char & buffer)
(
_buffer.swap (buffer);
Char * path = (char *) & _buffer.at (0);
_pathLen = strlen (path);
if (_pathLen 1 | | _pathLen = _buffer.size ())
membuang std:: exception ("Invalid format buffer");
_name = strrchr (path, '\ \');
if (_name)! _name path =;
lain + + _name;
/ / ON_MESSAGE ("- SampleParser dibuat -")
)
~ SampleParser ()
(
/ / ON_MESSAGE ("- SampleParser hancur -")
)
Char * GetName () (return _name;)
fungsi User-defined (UDFS) adalah host-bahasa program untuk melaksanakan tugas sering dibutuhkan, melengkapi built-in fungsi SQL seperti MIN () dan MAX (). UDFS adalah ekstensi untuk server Firebird dan melaksanakan sebagai bagian dari proses server. UDFS kata lain dikompilasi fungsi dan terkait dengan perpustakaan-link secara dinamis.
Apa yang Anda butuhkan
Untuk membaca artikel ini secara efektif Anda membutuhkan pengetahuan lanjutan dari C + +, C # dan Firebird SQL. Juga Anda memerlukan memiliki VS 2005 dengan C # dan C + + dipasang untuk membangun sampel. sampel telah memiliki "baterai dalam": semua file yang dibutuhkan untuk Firebird embedded server dan penyedia ADO.NET ditempatkan dalam folder Firebird sampel dan digunakan dalam membangun pasca-acara.
Contoh struktur proyek
\ Firebird. - Folder dengan semua file yang dibutuhkan untuk Firebird Embedded SQL Server
|? \ Meliputi. - Folder dengan *. h file yang dibutuhkan untuk mengkompilasi UDFS
|? \ Lib - folder. Dengan perpustakaan statis diperlukan untuk menghubungkan UDFS
\ MainApp. - Sampel dikelola aplikasi
\ SampleUdf. - UDFS sampel dll
Tentang sampel
Proyek sampel menunjukkan bagaimana untuk mentransfer data biner (BLOB) dari satu tabel menggunakan parser UDFS objek berbasis ke meja lain:
[Kode dari] MainApp. \ \ Batch.sql
CREATE TABLE "RowDataTable" (
"KUNCI Id" INTEGER NOT NULL PRIMARY
"Nilai" blob
)
CREATE TABLE "FSTable" (
"KUNCI Id" INTEGER NOT NULL PRIMARY
, "Nama" VARCHAR (256)
, "FullPath" VARCHAR (256)
, "CreationTime" TIMESTAMP
, "Atribut" INTEGER
, "Ukuran" BIGINT
) Menciptakan UDFS berbasis data biner parser
UDFS Deklarasi
Firebird SQL memiliki sintaks berikut untuk menyatakan UDF:
MENYATAKAN FUNGSI EKSTERNAL nama [datatype | CSTRING (int)
[, Datatype | CSTRING (int) ...]]
RETURNS (datatype [DENGAN NILAI] | CSTRING (int)) [FREE_IT]
RETURNS [] n PARAMETER
ENTRY_POINT 'entryname'
MODULE_NAME 'modulename'; Argumen
Deskripsi
nama
Nama UDF untuk digunakan dalam pernyataan SQL, dapat berbeda dari nama
fungsi tertentu setelah kata kunci ENTRY_POINT
datatype
Datatype dari masukan atau kembali parameter
• Semua parameter masukan diteruskan ke UDF dengan referensi
parameter Kembali • dapat lulus dengan nilai
• Tidak bisa sebuah elemen array
RETURNS
Menentukan nilai kembali dari fungsi. Perhatikan bahwa sintaks tidak memungkinkan untuk menyatakan bahwa tidak ada yang kembali UDF
DENGAN NILAI
Menetapkan bahwa nilai kembali harus dilalui oleh nilai bukan oleh referensi
CSTRING (int)
Menentukan UDF yang mengembalikan string int byte null-diakhiri panjang
FREE_IT
Membebaskan memori dialokasikan untuk nilai kembali setelah selesai menjalankan UDF. Parameter ini harus digunakan dengan alokasi memori ib_util_malloc dalam pelaksanaan fungsi UDF, It's terkandung dalam:
Header: Perpustakaan ib_util.h: DLL ib_util_ms.lib: ib_util.dll RETURNS PARAMETER n
Menentukan bahwa fungsi mengembalikan parameter input ke-n; diperlukan untuk kembali
Gumpalan
'Entryname'
Dikutip string menetapkan nama UDF dalam kode sumber dan disimpan dalam
UDF library
'Modulename'
Dikutip file spesifikasi mengidentifikasi dll yang berisi UDF
Semua dll dengan UDFS harus ditempatkan ke folder UDF di root aplikasi tempat fbembedded.dll disimpan. Ketika permintaan akan deklarasi untuk mesin Firebird eksekusi tidak memerlukan dll UDF untuk ditempatkan dalam folder UDF pada saat itu. Tapi ketika menjalankan beberapa query disimpan prosedur penciptaan yang berisi mesin panggilan UDF diperlukan akan memeriksa fungsi eksternal dalam dll.
Berikut adalah beberapa contoh deklarasi UDF dari proyek sampel:
[Kode dari] MainApp. \ \ Batch.sql
MENYATAKAN FUNGSI EKSTERNAL CreateParser
Blob
RETURNS INTEGER DENGAN NILAI
MODULE_NAME SampleUdf_CreateParser ENTRY_POINT '' 'SampleUdf'
MENYATAKAN FUNGSI EKSTERNAL DestroyParser
INTEGER
RETURNS INTEGER DENGAN NILAI
MODULE_NAME SampleUdf_DestroyParser ENTRY_POINT '' 'SampleUdf'
MENYATAKAN FUNGSI EKSTERNAL GetName
INTEGER
RETURNS CSTRING (256)
MODULE_NAME SampleUdf_GetName ENTRY_POINT '' 'SampleUdf'
MENYATAKAN FUNGSI EKSTERNAL GetCreationTime
INTEGER
RETURNS TIMESTAMP FREE_IT
MODULE_NAME SampleUdf_GetCreationTime ENTRY_POINT '' 'SampleUdf'
MENYATAKAN FUNGSI EKSTERNAL GetSize
INTEGER
RETURNS BIGINT
ENTRY_POINT 'SampleUdf_GetSize' MODULE_NAME 'SampleUdf' UDFS pelaksanaan
Seperti yang Anda tebak, saya menggunakan parameter tipe integer untuk mengirim objek parser yang dibuat dalam tumpukan SampleUdf.dll. Dengan parser segala objek sangat sederhana:
[Kode dari] main.cpp. SampleUdf \ \
kelas SampleParser
(
std:: vector _buffer char ;
size_t _pathLen;
char * _name;
publik:
SampleParser (std:: vector char & buffer)
(
_buffer.swap (buffer);
Char * path = (char *) & _buffer.at (0);
_pathLen = strlen (path);
if (_pathLen 1 | | _pathLen = _buffer.size ())
membuang std:: exception ("Invalid format buffer");
_name = strrchr (path, '\ \');
if (_name)! _name path =;
lain + + _name;
/ / ON_MESSAGE ("- SampleParser dibuat -")
)
~ SampleParser ()
(
/ / ON_MESSAGE ("- SampleParser hancur -")
)
Char * GetName () (return _name;)
Char * GetFullPath () (return (char *) dan _buffer.at (0);)
__int64 * GetCreationTime () (return (__int64 *) & _buffer.at (_pathLen + 1);)
int * GetAttributes () (return (int *) & _buffer.at (_pathLen + 1 + sizeof (__int64));)
__int64 * GetSize () (return (__int64 *) & _buffer.at (_pathLen + 1 +
sizeof (__int64) + sizeof (int));)
);
UDF berikutnya menunjukkan bagaimana parser dibuat dan juga bekerja dengan data blob:
extern "C" __declspec (dllexport) SampleParser * SampleUdf_CreateParser
(BLOBCALLBACK data)
(
mencoba
(
std:: vector buffer char (data- blob_total_length);
ISC_UCHAR * p = (ISC_UCHAR *) & buffer.front ();
untuk (ISC_LONG i = 0; blob_number_segments i data- ; i + +)
(
ISC_USHORT panjang = 0;
data- blob_get_segment (blob_handle data- , p, data- blob_max_segment, & panjang);
p + = panjang;
)
kembali baru SampleParser (buffer);
)
catch (std:: exception & ex)
(
ON_ERROR (ex.what ());
)
menangkap (...)
(
ON_ERROR ("Kesalahan tidak diketahui");
)
return 0;
)
Dan sekarang mari kita menunjukkan bagaimana menggunakan objek parser. Fungsi berikut juga menunjukkan cara untuk:
mengubah struktur FILETIME untuk Firebird TIMESTAMP menggunakan server tertanam alokasi memori, saat Anda mentransfer kepemilikan memori ke database engine extern "C" __declspec (dllexport) ISC_TIMESTAMP * SampleUdf_GetCreationTime (int * ptr)
(
mencoba
(
SampleParser * diri = (SampleParser *) (* ptr);
FILETIME localtime;
if (::! FileTimeToLocalFileTime ((* FILETIME const) self- GetCreationTime (), & localtime))
return 0;
SYSTEMTIME st;
if (::! FileTimeToSystemTime (& localtime, & st))
return 0;
ISC_TIMESTAMP * timestamp = (ISC_TIMESTAMP *) ib_util_malloc (sizeof (ISC_TIMESTAMP));
timestamp- timestamp_time = (st.wHour * 3.600.000 st.wMinute + * 60.000
+ St.wSecond * 1000 st.wMilliseconds +) * 10;
KATA hari = st.wDay;
KATA bulan = st.wMonth;
KATA tahun = st.wYear;
/ / Perhitungan sihir dari kode Penyedia ADO.NET
if (bulan 2)
bulan -= 3;
lain
(
bulan + = 9;
tahun -= 1;
)
KATA c = tahun / 100;
KATA ya = tahun - 100 * c;
timestamp- timestamp_date = ((146.097 * c) / 4 + (1.461 * ya) / 4
+ (153 * bulan + 2) / 5 + hari + 1.721.119-2.400.001);
kembali timestamp;
)
catch (std:: exception & ex)
(
ON_ERROR (ex.what ());
)
menangkap (...)
(
ON_ERROR ("Kesalahan tidak diketahui");
)
return 0;
)
Seperti yang Anda bisa melihat semua parameter masukan dan keluaran dalam implementasi UDF adalah petunjuk, kecuali parameter output dinyatakan dengan modifier NILAI OLEH. Tapi pengubah ini tidak dapat digunakan dengan semua jenis data (misalnya itu tidak kompatibel dengan TIMESTAMP, tapi kompatibel dengan BIGINT - perilaku aneh ini untuk jenis ukuran yang sama, bukan?)
Menggunakan UDFS
Prosedur tersimpan berikutnya menunjukkan cara menggunakan parser dibuat:
[Kode dari] MainApp. \ \ Batch.sql
CREATE PROSEDUR TransferData
RETURNS ("counter" INTEGER)
AS
MENYATAKAN VARIABLE "tmp" INTEGER;
MENYATAKAN VARIABLE "parserPtr" INTEGER;
MENYATAKAN VARIABLE "Nilai" blob;
MENYATAKAN VARIABLE "Nama" VARCHAR (256);
MENYATAKAN VARIABLE "FullPath" VARCHAR (256);
MENYATAKAN VARIABLE "CreationTime" TIMESTAMP;
MENYATAKAN VARIABLE "Atribut" INTEGER;
MENYATAKAN VARIABLE "Ukuran" BIGINT;
BEGIN
"Counter" = 0;
UNTUK PILIH "Nilai" FROM "RowDataTable" KE: "Nilai" DO BEGIN
SELECT CreateParser (: "Nilai") FROM RDB database $ KE: "parserPtr";
JIKA ("parserPtr" IS NOT NULL) THEN BEGIN
SELECT GetName (: "parserPtr") FROM RDB $ database KE: "Nama";
SELECT GetFullPath (: "parserPtr") FROM RDB $ database KE: "FullPath";
SELECT GetCreationTime (: "parserPtr") FROM RDB $ database KE: "CreationTime";
SELECT GetAttributes (: "parserPtr") FROM RDB $ database KE: "Atribut";
SELECT GetSize (: "parserPtr") FROM RDB $ database KE: "Ukuran";
"Tmp GEN_ID" = ("FSTable_Generator", 1);
INSERT INTO "FSTable" ("Id" Nama, "", "FullPath", "CreationTime",
"Atribut", "Ukuran")
VALUES (: "tmp",: "Nama",: "FullPath",: "CreationTime",: "Atribut",: "Ukuran");
"Counter" = "counter" + 1;
SELECT DestroyParser (: "parserPtr") FROM RDB $ database KE: "tmp";
AKHIR
AKHIR
Suspend;
AKHIR Tentang aneh bentuk panggilan:
SELECT UDF_Name ( Parameters_List ) FROM RDB $ database KE Output_parameter Ini satu-satunya cara untuk membuatnya bekerja dalam tertanam dll server:)
Di luar inisialisasi
Berkat jendela caching ada kemungkinan untuk me-load dan menginisialisasi UDFS dll sebelum dimuat oleh mesin database Firebird. Dalam sampel saya kemungkinan ini digunakan untuk membuat beberapa callback berguna:
[Kode dari \ MainApp. \ SampleProvider.cs]
void delegasi swasta MessageCallbackDelegate (
[MarshalAs (UnmanagedType.LPStr)] pesan string);
swasta statis MessageCallbackDelegate messageCallback;
swasta statis MessageCallbackDelegate errorCallback;
[Dllimport ("UDF / SampleUdf")]
extern void swasta statis RegisterCallbacks (MessageCallbackDelegate
messageCallback, MessageCallbackDelegate errorCallback);
statis SampleProvider ()
(
messageCallback = MessageCallback;
errorCallback = ErrorCallback;
RegisterCallbacks (messageCallback, errorCallback);
)
[Kode dari] main.cpp. SampleUdf \ \
typedef void (__stdcall * FCallback) (pesan * const char);
FCallback g_messageCallback = 0;
FCallback g_errorCallback = 0;
//------------------------------------------------ ---------------------------
# Define ON_MESSAGE (berantakan) (if (g_messageCallback) g_messageCallback (mess);)
# Define ON_ERROR (berantakan) (if (g_errorCallback) g_errorCallback (mess);)
//------------------------------------------------ ---------------------------
extern "C" __declspec (dllexport) void RegisterCallbacks (FCallback messageCallback,
FCallback errorCallback)
(
g_messageCallback = messageCallback;
g_errorCallback = errorCallback;
)
Dan ketika mesin database Firebird akan mencoba untuk UDFS beban dll itu akan menggunakan Anda sudah diambil dan diinisialisasi perpustakaan.
Kesimpulan
Maka dengan ini artikel yang Anda lihat, bagaimana proses berbagi ruang nama alamat memungkinkan Anda untuk menggunakan benda-benda asli atau dikelola UDFS Anda.
Download source code.
__int64 * GetCreationTime () (return (__int64 *) & _buffer.at (_pathLen + 1);)
int * GetAttributes () (return (int *) & _buffer.at (_pathLen + 1 + sizeof (__int64));)
__int64 * GetSize () (return (__int64 *) & _buffer.at (_pathLen + 1 +
sizeof (__int64) + sizeof (int));)
);
UDF berikutnya menunjukkan bagaimana parser dibuat dan juga bekerja dengan data blob:
extern "C" __declspec (dllexport) SampleParser * SampleUdf_CreateParser
(BLOBCALLBACK data)
(
mencoba
(
std:: vector buffer char (data- blob_total_length);
ISC_UCHAR * p = (ISC_UCHAR *) & buffer.front ();
untuk (ISC_LONG i = 0; blob_number_segments i data- ; i + +)
(
ISC_USHORT panjang = 0;
data- blob_get_segment (blob_handle data- , p, data- blob_max_segment, & panjang);
p + = panjang;
)
kembali baru SampleParser (buffer);
)
catch (std:: exception & ex)
(
ON_ERROR (ex.what ());
)
menangkap (...)
(
ON_ERROR ("Kesalahan tidak diketahui");
)
return 0;
)
Dan sekarang mari kita menunjukkan bagaimana menggunakan objek parser. Fungsi berikut juga menunjukkan cara untuk:
mengubah struktur FILETIME untuk Firebird TIMESTAMP menggunakan server tertanam alokasi memori, saat Anda mentransfer kepemilikan memori ke database engine extern "C" __declspec (dllexport) ISC_TIMESTAMP * SampleUdf_GetCreationTime (int * ptr)
(
mencoba
(
SampleParser * diri = (SampleParser *) (* ptr);
FILETIME localtime;
if (::! FileTimeToLocalFileTime ((* FILETIME const) self- GetCreationTime (), & localtime))
return 0;
SYSTEMTIME st;
if (::! FileTimeToSystemTime (& localtime, & st))
return 0;
ISC_TIMESTAMP * timestamp = (ISC_TIMESTAMP *) ib_util_malloc (sizeof (ISC_TIMESTAMP));
timestamp- timestamp_time = (st.wHour * 3.600.000 st.wMinute + * 60.000
+ St.wSecond * 1000 st.wMilliseconds +) * 10;
KATA hari = st.wDay;
KATA bulan = st.wMonth;
KATA tahun = st.wYear;
/ / Perhitungan sihir dari kode Penyedia ADO.NET
if (bulan 2)
bulan -= 3;
lain
(
bulan + = 9;
tahun -= 1;
)
KATA c = tahun / 100;
KATA ya = tahun - 100 * c;
timestamp- timestamp_date = ((146.097 * c) / 4 + (1.461 * ya) / 4
+ (153 * bulan + 2) / 5 + hari + 1.721.119-2.400.001);
kembali timestamp;
)
catch (std:: exception & ex)
(
ON_ERROR (ex.what ());
)
menangkap (...)
(
ON_ERROR ("Kesalahan tidak diketahui");
)
return 0;
)
Seperti yang Anda bisa melihat semua parameter masukan dan keluaran dalam implementasi UDF adalah petunjuk, kecuali parameter output dinyatakan dengan modifier NILAI OLEH. Tapi pengubah ini tidak dapat digunakan dengan semua jenis data (misalnya itu tidak kompatibel dengan TIMESTAMP, tapi kompatibel dengan BIGINT - perilaku aneh ini untuk jenis ukuran yang sama, bukan?)
Menggunakan UDFS
Prosedur tersimpan berikutnya menunjukkan cara menggunakan parser dibuat:
[Kode dari] MainApp. \ \ Batch.sql
CREATE PROSEDUR TransferData
RETURNS ("counter" INTEGER)
AS
MENYATAKAN VARIABLE "tmp" INTEGER;
MENYATAKAN VARIABLE "parserPtr" INTEGER;
MENYATAKAN VARIABLE "Nilai" blob;
MENYATAKAN VARIABLE "Nama" VARCHAR (256);
MENYATAKAN VARIABLE "FullPath" VARCHAR (256);
MENYATAKAN VARIABLE "CreationTime" TIMESTAMP;
MENYATAKAN VARIABLE "Atribut" INTEGER;
MENYATAKAN VARIABLE "Ukuran" BIGINT;
BEGIN
"Counter" = 0;
UNTUK PILIH "Nilai" FROM "RowDataTable" KE: "Nilai" DO BEGIN
SELECT CreateParser (: "Nilai") FROM RDB database $ KE: "parserPtr";
JIKA ("parserPtr" IS NOT NULL) THEN BEGIN
SELECT GetName (: "parserPtr") FROM RDB $ database KE: "Nama";
SELECT GetFullPath (: "parserPtr") FROM RDB $ database KE: "FullPath";
SELECT GetCreationTime (: "parserPtr") FROM RDB $ database KE: "CreationTime";
SELECT GetAttributes (: "parserPtr") FROM RDB $ database KE: "Atribut";
SELECT GetSize (: "parserPtr") FROM RDB $ database KE: "Ukuran";
"Tmp GEN_ID" = ("FSTable_Generator", 1);
INSERT INTO "FSTable" ("Id" Nama, "", "FullPath", "CreationTime",
"Atribut", "Ukuran")
VALUES (: "tmp",: "Nama",: "FullPath",: "CreationTime",: "Atribut",: "Ukuran");
"Counter" = "counter" + 1;
SELECT DestroyParser (: "parserPtr") FROM RDB $ database KE: "tmp";
AKHIR
AKHIR
Suspend;
AKHIR Tentang aneh bentuk panggilan:
SELECT UDF_Name ( Parameters_List ) FROM RDB $ database KE Output_parameter Ini satu-satunya cara untuk membuatnya bekerja dalam tertanam dll server:)
Di luar inisialisasi
Berkat jendela caching ada kemungkinan untuk me-load dan menginisialisasi UDFS dll sebelum dimuat oleh mesin database Firebird. Dalam sampel saya kemungkinan ini digunakan untuk membuat beberapa callback berguna:
[Kode dari \ MainApp. \ SampleProvider.cs]
void delegasi swasta MessageCallbackDelegate (
[MarshalAs (UnmanagedType.LPStr)] pesan string);
swasta statis MessageCallbackDelegate messageCallback;
swasta statis MessageCallbackDelegate errorCallback;
[Dllimport ("UDF / SampleUdf")]
extern void swasta statis RegisterCallbacks (MessageCallbackDelegate
messageCallback, MessageCallbackDelegate errorCallback);
statis SampleProvider ()
(
messageCallback = MessageCallback;
errorCallback = ErrorCallback;
RegisterCallbacks (messageCallback, errorCallback);
)
[Kode dari] main.cpp. SampleUdf \ \
typedef void (__stdcall * FCallback) (pesan * const char);
FCallback g_messageCallback = 0;
FCallback g_errorCallback = 0;
//------------------------------------------------ ---------------------------
# Define ON_MESSAGE (berantakan) (if (g_messageCallback) g_messageCallback (mess);)
# Define ON_ERROR (berantakan) (if (g_errorCallback) g_errorCallback (mess);)
//------------------------------------------------ ---------------------------
extern "C" __declspec (dllexport) void RegisterCallbacks (FCallback messageCallback,
FCallback errorCallback)
(
g_messageCallback = messageCallback;
g_errorCallback = errorCallback;
)
Dan ketika mesin database Firebird akan mencoba untuk UDFS beban dll itu akan menggunakan Anda sudah diambil dan diinisialisasi perpustakaan.
Kesimpulan
Maka dengan ini artikel yang Anda lihat, bagaimana proses berbagi ruang nama alamat memungkinkan Anda untuk menggunakan benda-benda asli atau dikelola UDFS Anda.
Download source code.
Tidak ada komentar:
Posting Komentar