Thrift
The QueryCat plugin can be written as a separate executable. The interaction between QueryCat host and plugin is implemented using Apache Thrift protocol.
[+] Any language can be used for development. [-] Might be harder to develop. [-] In some cases the performance can be low.
Technical Information
- protocol: binary;
- transport: named pipes on Windows and sockets on Linux;
The QueryCat host starts your plugin with the following command line arguments:
--server-pipe-name. The address of socket or names pipe channel.--token. The special auth token that should be provided on registration. It is needed to prevent unauthorized access.--parent-pid. The QueryCat process identifier.
Guide
The guide below describes how to write a plugin.
.NET Approach With Executable
Using this approach you will prepare the separate executable that interacts directly with QueryCat host:
QueryCat Host <---> Plugin Executable
-
Create a new empty console application project.
dotnet new console --name SimplePluginNOTE: The plugin must contain "Plugin" (case insensitive) word in its name.
-
Reference
QueryCat.Plugins.Clientproject: NuGet. For example:<ItemGroup> <PackageReference Include="QueryCat.Plugins.Client" Version="0.11.0" /> </ItemGroup> -
Implement functions and rows inputs.
-
Register them within
Program.cs, for example:public class Program { internal static async Task Main(string[] args) { ThriftPluginClient.SetupApplicationLogging(); using var client = new ThriftPluginClient(ThriftPluginClient.ConvertCommandLineArguments(args)); client.FunctionsManager.RegisterFunction(TestFunctions.TestCombineFunction); await client.StartAsync(); await client.WaitForServerExitAsync(); } } -
Compile your application into
.exefile:dotnet build -c:Release -r linux-x64 -p:PublishSingleFile=true
For debug, you can run your plugin with following arguments:
--debug-server="/opt/qcat"
--debug-server-file="/home/ivan/github.sql"
or
--debug-server="/opt/qcat"
--debug-server-query="select 'some SQL';"
It will enforce QueryCat to run your plugin with the specific query.
.NET Approach With NuGet
Using this approach you will prepare the NuGet package (or .NET dll) that will interact with QueryCat host with proxy special proxy.
QueryCat Host <---> QueryCat Proxy <---> Plugin Executable
-
Create a new empty library application project.
dotnet new classlib --name SimplePluginNOTE: The plugin must contain "Plugin" (case-insensitive) word in its name.
-
Reference QueryCat library: NuGet.
<ItemGroup> <PackageReference Include="QueryCat" Version="0.11.0" /> </ItemGroup> -
Create the new class
SampleFunction.csfor a function. For example:public class SampleFunction { [SafeFunction] [Description("Get a random number.")] [FunctionSignature("random_number(): int")] public static VariantValue RandomNumberFunction(IExecutionThread thread) { return new VariantValue(Random.Shared.Next()); } }Note: You can also use async implementation for function:
[SafeFunction] [Description("Get a random number.")] [FunctionSignature("random_number(): int")] public static ValueTask<VariantValue> RandomNumberFunctionAsync(IExecutionThread thread, CancellationToken cancellationToken) { var value = new VariantValue(Random.Shared.Next()); return ValueTask.FromResult(value); } -
Create the new static class in the library namespace root:
public static class Registration { public static void RegisterFunctions(IFunctionsManager functionsManager) { // Register your functions here. functionsManager.RegisterFunction(SampleFunction.RandomNumberFunction); } public static Task OnLoadAsync(IExecutionThread executionThread, CancellationToken cancellationToken) { // You can put plugin initialization code here. return Task.CompletedTask; } } -
Publish as NuGet package.
dotnet pack
-
Test.
qcat query "random_number()" --plugin-dirs=/home/user/sample-plugin/SamplePlugin/bin/Release/
Other Languages Approach
Use the following Thrift file to generate a proxy: https://github.com/krasninja/querycat/blob/develop/sdk/QueryCat.thrift .
-
Handle command line arguments to properly connect to QueryCat host.
-
Call the
RegisterPluginfunction ofPluginsManagerservice.
Plugin Registration Process
-
Once observed, the QueryCat host starts temporary registration server (using named pipes on Windows or Unix socket) and runs the plugin executable with the following arguments:
server-pipe-name,token,parent-pid. See above for additional information. -
The plugin should connect to the host and call
RegisterPluginmethod. It should be done within 10 seconds. -
The host keeps the connection and can call plugins' functions using
CallFunctionmethod.
Debug Mode
To debug your plugins easier, the QueryCat has a special command. It will call your plugin in a special test mode.
qcat plugin debug
In that mode the server pipe name will always be qcat-test and token will be test.