Was this helpful?
Install Plug-in from .NET Application
Add the following to your .NET application to install a custom plug-in.
using Ingres.Client.<plugin_name>
namespace <your application name>
{
public <app_method>
{
<plugin_name>.Install();
Custom Plugin Example – Joinop
The following Joinop plug-in example, if installed and set on the connection string (for example, joinop=greedy), sends a SET JOINOP statement with the appropriate value to the DBMS after the connection is established.
<File JoinopPlugin.cs>
 
using Ingres.Plugins;
using Ingres.Utility;
 
using System.Text.RegularExpressions;
 
namespace Ingres.Client.Joinop
 
 
{
/// <summary>
/// This plugin sets the session joinop mode for the connection.
/// </summary>
public class JoinopPlugin : Plugin
{
private static bool _installed = false;
 
 
/// <summary>
/// Installs this plugin
/// </summary>
public static void Install()
{
if (_installed)
return;
_installed = true;
IngresPlugins.Add(new JoinopPlugin());
}
 
/// <summary>
/// Creates a new instance of <see cref="JoinopPlugin"/>
/// <para>
/// Defines connection string parameter "Joinop", which can take one of:
/// <list type="bullet">
/// <item>
/// <c>notimeout</c> - the optimizer searches ALL possible query plans.
/// </item>
/// <item>
/// <c>timeout nnn</c> - the query optimizer stops looking for query
/// execution plans after the specified number of milliseconds and
/// uses the best plan found to that point.
/// </item>
/// <item>
/// <c>timeoutabort nnn</c> - nnn specifies the time in milliseconds after
/// which the optimizer stops considering query plans and uses the best
/// plan found to that point. If no plan is found within the specified time,
/// an error is generated.
/// </item>
/// <item>
/// <c>greedy</c> - the greedy heuristic enables the optimizer to produce a
/// query plan much faster than with its default technique of exhaustive
/// searching for query execution plans when the query references a large
/// number of tables.
/// </item>
/// </list>
/// </para>
/// </summary>
private JoinopPlugin() : base(
StringParameter("Joinop")
)
{
}
 
/// <summary>
/// Returns <c>true</c> if the connection string parameter "Joinop" has a value.
/// </summary>
/// <param name="config">The configuration from the connection string</param>
/// <returns><c>true</c> if the connection string parameter "Joinop" has a value.</returns>
public override bool IsEnabled(IConfig config)
{
// Enabled if connection string parameter "Joinop" has a value
return !string.IsNullOrWhiteSpace(config.GetString("Joinop"));
}
 
private static readonly Regex JoinopRe = new Regex(@"^\s*(?:timeout\s+\d+|notimeout|timeoutabort\s+\d+|greedy|nogreedy)\s*$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
 
/// <summary>
/// Executes <code>SET JOINOP ...</code> in the specified connection
/// </summary>
/// <param name="connection">The specified connection</param>
/// <param name="config">The configuration from the connection string</param>
public override void ConnectionOpened(IngresConnection connection, IConfig config)
{
using (var command = connection.CreateCommand())
{
var value = config.GetString("Joinop")?.Trim();
 
if (string.IsNullOrWhiteSpace(value))
{
// This should never happen
throw new IngresException($"Joinop is not defined");
}
 
if (!JoinopRe.IsMatch(value))
{
throw new IngresException($"Unknown joinop: {value}");
}
 
command.CommandText = $"SET JOINOP {value.ToUpperInvariant()}";
command.ExecuteNonQuery();
}
}
}
}
Custom Plugin Example – TrimChars
The following TrimChars plug-in example trims trailing spaces from char and nchar data type values. It must be installed and set in the connection string (for example, trimchars=yes). It is split across three files.
<File TrimCharsPlugin.cs>
 
using Ingres.Plugins;
using Ingres.Utility;
 
using static Ingres.Utility.DbmsConst;
 
namespace Ingres.Client.TrimChars
{
/// <summary>
/// When enabled this plugin trims trailing spaces from <c>char()</c> values
/// </summary>
public class TrimCharsPlugin : Plugin
{
private static bool _installed = false;
 
/// <summary>
/// Installs this plugin
/// </summary>
public static void Install()
{
if (_installed)
return;
_installed = true;
IngresPlugins.Add(new TrimCharsPlugin());
}
 
private TrimCharsPlugin() : base(
BoolParameter("Trim Chars", "Trim_Chars", "Trim-Chars", "TrimChars")
)
{
}
 
/// <inheritdoc />
public override bool IsEnabled(IConfig config)
{
return config.GetBoolean("Trim Chars", false);
}
 
/// <inheritdoc />
public override SqlData GetSqlData(IConnection conn, IInputMessage message, string name, ProviderType providerType, short dbmsType, short length)
{
switch (providerType)
{
case ProviderType.Char:
case ProviderType.NChar:
if (dbmsType != DBMS_TYPE_NCHAR)
return new SqlTrimmedChar(conn, message.getCharSet(), length);
else
return new SqlTrimmedNChar(conn, length / 2);
}
return null;
}
}
}
 
 
<File SqlTrimmedChar.cs>
using Ingres.Utility;
 
using System;
 
namespace Ingres.Plugins.TrimChars
{
public class SqlTrimmedChar : SqlChar
{
public SqlTrimmedChar(IConnection conn, CharSet charSet, int size)
: base(conn, charSet, size)
{
}
 
public virtual void trim()
{
if (length <= 0)
return;
 
byte space;
 
try { space = charSet.getSpaceChar(); }
catch (Exception)
{ space = 0x20; /* Use ASCII space as default */ }
 
while (length > 0 && value[length - 1] == space) length -= 1;
}
 
/// <summary>
/// Trim instead of extend
/// </summary>
public override void extend()
{
trim();
}
 
/// <inheritdoc/>
public override byte get(int position)
{
trim();
return base.get(position);
}
 
/// <inheritdoc/>
public override byte[] get()
{
trim();
return base.get();
}
 
/// <inheritdoc/>
public override int get(int position, int length, byte[] value, int offset)
{
trim();
return base.get(position, length, value, offset);
}
 
/// <inheritdoc/>
public override string getString()
{
trim();
return base.getString();
}
 
/// <inheritdoc/>
public override string getString(int limit)
{
trim();
return base.getString(limit);
}
}
}
 
<File SqlTrimmedNChar.cs>
using Ingres.Utility;
 
namespace Ingres.Plugins.TrimChars
{
public class SqlTrimmedNChar : SqlNChar
{
public SqlTrimmedNChar(IConnection conn, int size)
: base(conn, size)
{
}
 
public virtual void trim()
{
if (length <= 0)
return;
var space = ' ';
while (length > 0 && value[length - 1] == space) length -= 1;
}
 
/// <summary>
/// Trim instead of extend
/// </summary>
public override void extend()
{
trim();
}
 
/// <inheritdoc/>
public override char get(int position)
{
trim();
return base.get(position);
}
 
/// <inheritdoc/>
public override char[] get()
{
trim();
return base.get();
}
 
/// <inheritdoc/>
public override int get(int position, int length, char[] value, int offset)
{
trim();
return base.get(position, length, value, offset);
}
 
/// <inheritdoc/>
public override string getString()
{
trim();
return base.getString();
}
 
/// <inheritdoc/>
public override string getString(int limit)
{
trim();
return base.getString(limit);
}
}
}
Last modified date: 11/09/2022