csharp #fire #xaf的#firebird连接提供程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp #fire #xaf的#firebird连接提供程序相关的知识,希望对你有一定的参考价值。
using System;
using System.Collections;
using System.Data;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using DevExpress.Xpo.DB;
using System.Globalization;
using DevExpress.Data.Filtering;
using DevExpress.Xpo;
using DevExpress.Xpo.DB.Exceptions;
using DevExpress.Xpo.DB.Helpers;
using FirebirdSql.Data.FirebirdClient;
using System.Text;
namespace TCMSOFT.Xpo.Providers.Firebird
{
public enum FirebirdServerType { Server = 0, Embedded = 1 }
public class Firebird3ConnectionProvider : ConnectionProviderSql
{
public const string XpoProviderTypeString = "Firebird3";
ReflectConnectionHelper helper;
ReflectConnectionHelper ConnectionHelper
{
get
{
if (helper == null)
helper = new ReflectConnectionHelper(Connection, "FirebirdSql.Data.FirebirdClient.FbException");
return helper;
}
}
public static string GetConnectionString(string server, int port, string userid, string password, string database, FirebirdServerType serverType, string charset)
{
FbConnectionStringBuilder cs = new FbConnectionStringBuilder();
cs.DataSource = server;
cs.Port = 3050;
cs.UserID = userid;
cs.Password = password;
cs.Database = database;
cs.Dialect = 3;
cs.Charset = charset;
switch (serverType)
{
case FirebirdServerType.Server:
cs.ServerType = FbServerType.Default;
break;
case FirebirdServerType.Embedded:
cs.ServerType = FbServerType.Embedded;
break;
}
cs.Pooling = false;
return $"{DataStoreBase.XpoProviderTypeParameterName}={XpoProviderTypeString};{cs}";
}
public static string GetConnectionString(string server, string userid, string password, string database, FirebirdServerType serverType, string charset)
{
return GetConnectionString(server, 3050, userid, password, database, serverType, charset);
}
public static string GetConnectionString(string userid, string password, string database)
{
return GetConnectionString("localhost", userid, password, database, FirebirdServerType.Embedded, "UTF8");
}
public static string GetConnectionString(string server, string userid, string password, string database)
{
return GetConnectionString(server, userid, password, database, FirebirdServerType.Server, "UTF8");
}
public static string GetConnectionString(string server, string userid, string password, string database, string charset)
{
return GetConnectionString(server, userid, password, database, FirebirdServerType.Server, charset);
}
public static IDataStore CreateProviderFromString(string connectionString, AutoCreateOption autoCreateOption, out IDisposable[] objectsToDisposeOnDisconnect)
{
IDbConnection connection = CreateConnection(connectionString);
objectsToDisposeOnDisconnect = new IDisposable[] { connection };
return CreateProviderFromConnection(connection, autoCreateOption);
}
public static IDataStore CreateProviderFromConnection(IDbConnection connection, AutoCreateOption autoCreateOption)
{
return new Firebird3ConnectionProvider(connection, autoCreateOption);
}
static Firebird3ConnectionProvider()
{
RegisterDataStoreProvider(XpoProviderTypeString, new DataStoreCreationFromStringDelegate(CreateProviderFromString));
RegisterDataStoreProvider("FbConnection", new DataStoreCreationFromConnectionDelegate(CreateProviderFromConnection));
RegisterFactory(new FirebirdProviderFactory());
}
public static void Register() { }
public Firebird3ConnectionProvider(IDbConnection connection, AutoCreateOption autoCreateOption)
: base(connection, autoCreateOption)
{
ReadDbVersion(connection);
}
decimal? versionMajor;
int versionMinor;
void ReadDbVersion(IDbConnection conn)
{
try
{
using (IDbCommand c = CreateCommand(new Query("SELECT rdb$get_context('SYSTEM', 'ENGINE_VERSION') as version from rdb$database")))
{
object result = c.ExecuteScalar();
if (result != null && result is string)
{
SetServerVersionInternal((string)result);
}
}
}
catch { }
}
bool SetServerVersionInternal(string versionString)
{
string[] versionParts = versionString.Split('.');
decimal versionMajorLocal;
if (versionParts.Length == 3 && decimal.TryParse(string.Concat(versionParts[0], ".", versionParts[1]), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out versionMajorLocal) && int.TryParse(versionParts[2], out versionMinor))
{
versionMajor = versionMajorLocal;
return true;
}
return false;
}
bool SupportVersion(decimal major, int minor)
{
if (!versionMajor.HasValue)
return false;
if (versionMajor.Value > major)
return true;
if (versionMajor.Value == major && versionMinor >= minor)
return true;
return false;
}
public void SetServerVersion(string versionString)
{
if (!SetServerVersionInternal(versionString))
{
throw new ArgumentException("versionString");
}
}
protected override string GetSqlCreateColumnTypeForBoolean(DBTable table, DBColumn column)
{
return "boolean";
}
protected override string GetSqlCreateColumnTypeForByte(DBTable table, DBColumn column)
{
return "numeric(3,0)";
}
protected override string GetSqlCreateColumnTypeForSByte(DBTable table, DBColumn column)
{
return "numeric(3,0)";
}
protected override string GetSqlCreateColumnTypeForChar(DBTable table, DBColumn column)
{
return "char CHARACTER SET UTF8";
}
protected override string GetSqlCreateColumnTypeForDecimal(DBTable table, DBColumn column)
{
return "decimal(18,4)";
}
protected override string GetSqlCreateColumnTypeForDouble(DBTable table, DBColumn column)
{
return "double precision";
}
protected override string GetSqlCreateColumnTypeForSingle(DBTable table, DBColumn column)
{
return "float";
}
protected override string GetSqlCreateColumnTypeForInt32(DBTable table, DBColumn column)
{
return "integer";
}
protected override string GetSqlCreateColumnTypeForUInt32(DBTable table, DBColumn column)
{
return "numeric(10,0)";
}
protected override string GetSqlCreateColumnTypeForInt16(DBTable table, DBColumn column)
{
return "smallint";
}
protected override string GetSqlCreateColumnTypeForUInt16(DBTable table, DBColumn column)
{
return "numeric(5,0)";
}
protected override string GetSqlCreateColumnTypeForInt64(DBTable table, DBColumn column)
{
return "bigint";
}
protected override string GetSqlCreateColumnTypeForUInt64(DBTable table, DBColumn column)
{
return "numeric(18,0)";
}
public const int MaximumStringSize = 4000;
protected override string GetSqlCreateColumnTypeForString(DBTable table, DBColumn column)
{
if (column.Size > 0 && column.Size <= MaximumStringSize)
return "char varying (" + column.Size.ToString(CultureInfo.InvariantCulture) + ") CHARACTER SET UTF8";
else
return "BLOB SUB_TYPE TEXT";
}
protected override string GetSqlCreateColumnTypeForDateTime(DBTable table, DBColumn column)
{
return "timestamp";
}
protected override string GetSqlCreateColumnTypeForGuid(DBTable table, DBColumn column)
{
return "char(36)";
}
protected override string GetSqlCreateColumnTypeForByteArray(DBTable table, DBColumn column)
{
return "blob";
}
public override string GetSqlCreateColumnFullAttributes(DBTable table, DBColumn column)
{
string result = GetSqlCreateColumnType(table, column);
if (column.IsKey)
result += " NOT NULL";
return result;
}
protected override object ReformatReadValue(object value, ConnectionProviderSql.ReformatReadValueArgs args)
{
if (args.TargetTypeCode == TypeCode.Boolean && args.DbTypeCode == TypeCode.String)
return ((string)value).TrimEnd() != "0";
return base.ReformatReadValue(value, args);
}
protected override object ConvertToDbParameter(object clientValue, TypeCode clientValueTypeCode)
{
switch (clientValueTypeCode)
{
case TypeCode.Object:
if (clientValue is Guid)
{
return clientValue.ToString();
}
break;
case TypeCode.Byte:
return (Int16)(Byte)clientValue;
case TypeCode.SByte:
return (Int16)(SByte)clientValue;
case TypeCode.UInt16:
return (Int32)(UInt16)clientValue;
case TypeCode.UInt32:
return (Int64)(UInt32)clientValue;
case TypeCode.UInt64:
return (Decimal)(UInt64)clientValue;
case TypeCode.Single:
return (Double)(Single)clientValue;
case TypeCode.Boolean:
return ((Boolean)clientValue) ? "true" : "false";
}
return base.ConvertToDbParameter(clientValue, clientValueTypeCode);
}
protected virtual string GetSeqName(string tableName)
{
return ComposeSafeConstraintName("sq_" + tableName);
}
class IdentityInsertSqlGenerator : BaseObjectSqlGenerator
{
protected override string InternalGenerateSql()
{
StringBuilder names = new StringBuilder();
StringBuilder values = new StringBuilder();
for (int i = 0; i < Root.Operands.Count; i++)
{
names.AppendFormat(CultureInfo.InvariantCulture, "{0},", Process(Root.Operands[i]));
values.Append(GetNextParameterName(((InsertStatement)Root).Parameters[i]) + ",");
}
names.AppendFormat(CultureInfo.InvariantCulture, "\"{0}\",", formatter.ComposeSafeColumnName(((InsertStatement)Root).IdentityColumn));
values.Append("@seq,");
return formatter.FormatInsert(formatter.FormatTable(formatter.ComposeSafeSchemaName(Root.Table.Name), formatter.ComposeSafeTableName(Root.Table.Name)),
names.ToString(0, names.Length - 1),
values.ToString(0, values.Length - 1));
}
public IdentityInsertSqlGenerator(ISqlGeneratorFormatter formatter, TaggedParametersHolder identitiesByTag)
: base(formatter, identitiesByTag, new Dictionary<OperandValue, string>())
{
}
}
protected override Int64 GetIdentity(InsertStatement root, TaggedParametersHolder identitiesByTag)
{
string seq = GetSeqName(root.Table.Name);
object value = GetScalar(new Query(string.Concat("select GEN_ID(\"", seq, "\", 1) from RDB$DATABASE")));
Query sql = new IdentityInsertSqlGenerator(this, identitiesByTag).GenerateSql(root);
long resultId;
switch (root.IdentityColumnType)
{
case DBColumnType.Int32:
{
int id = ((IConvertible)value).ToInt32(CultureInfo.InvariantCulture);
sql.Parameters.Add(new OperandValue(id));
resultId = id;
}
break;
case DBColumnType.Int64:
{
long id = ((IConvertible)value).ToInt64(CultureInfo.InvariantCulture);
sql.Parameters.Add(new OperandValue(id));
resultId = id;
}
break;
default:
throw new NotSupportedException();
}
sql.ParametersNames.Add("@seq");
ExecSql(sql);
return resultId;
}
protected override Exception WrapException(Exception e, IDbCommand query)
{
object o;
if (ConnectionHelper.TryGetExceptionProperty(e, "Errors", out o))
{
foreach (object error in (IEnumerable)o)
{
int number = (int)ReflectConnectionHelper.GetPropertyValue(error, "Number");
if (number == 0x14000102 || number == 0x14000104 || number == 0x140000f9)
return new SchemaCorrectionNeededException((string)ReflectConnectionHelper.GetPropertyValue(error, "Message"), e);
if (number == 0x14000092 || number == 0x14000159 || number == 0x1400001d)
return new ConstraintViolationException(query.CommandText, GetParametersString(query), e);
}
}
return base.WrapException(e, query);
}
protected override IDbConnection CreateConnection()
{
return ConnectionHelper.GetConnection(ConnectionString);
}
public static IDbConnection CreateConnection(string connectionString)
{
return ReflectConnectionHelper.GetConnection("FirebirdSql.Data.FirebirdClient", "FirebirdSql.Data.FirebirdClient.FbConnection", connectionString);
}
protected override void CreateDataBase()
{
const int CannotOpenDatabaseError = 0x14000018;
using (IDbConnection conn = ConnectionHelper.GetConnection(ConnectionString))
{
try
{
conn.Open();
}
catch (Exception e)
{
object[] values;
object errorFirstItem;
if (ConnectionHelper.TryGetExceptionProperties(e, new string[] { "ErrorCode", "Errors" }, out values)
&& (
(int)values[0] == CannotOpenDatabaseError ||
((errorFirstItem = ReflectConnectionHelper.GetCollectionFirstItem((IEnumerable)values[1])) != null)
&& ((int)ReflectConnectionHelper.GetPropertyValue(errorFirstItem, "Number")) == CannotOpenDatabaseError)
&& CanCreateDatabase)
{
ReflectConnectionHelper.InvokeStaticMethod(ConnectionHelper.ConnectionType, "CreateDataBase", new object[] { ConnectionString }, true);
}
else
{
throw new UnableToOpenDatabaseException(ConnectionString, e);
}
}
}
}
delegate bool TablesFilter(DBTable table);
SelectStatementResult GetDataForTables(ICollection tables, TablesFilter filter, string queryText)
{
QueryParameterCollection parameters = new QueryParameterCollection();
StringCollection inList = new StringCollection();
int i = 0;
foreach (DBTable table in tables)
{
if (filter == null || filter(table))
{
parameters.Add(new OperandValue(ComposeSafeTableName(table.Name)));
inList.Add("@p"+ i.ToString(CultureInfo.InvariantCulture));
++i;
}
}
if (inList.Count == 0)
return new SelectStatementResult();
Query query =
new Query(
string.Format(CultureInfo.InvariantCulture, queryText, StringListHelper.DelimitedText(inList, ",")),
parameters, inList);
return SelectData(query);
}
DBColumnType GetTypeFromString(short type, short subType, short scale, short size)
{
switch (type)
{
case 7:
if (subType == 2)
{
return DBColumnType.Decimal;
}
if (subType == 1)
{
return DBColumnType.Decimal;
}
if (scale < 0)
{
return DBColumnType.Decimal;
}
return DBColumnType.Int16;
case 8:
if (subType == 2)
{
return DBColumnType.Decimal;
}
if (subType == 1)
{
return DBColumnType.Decimal;
}
if (scale < 0)
{
return DBColumnType.Decimal;
}
return DBColumnType.Int32;
case 9:
case 0x10:
case 0x2d:
if (subType == 2)
{
return DBColumnType.Decimal;
}
if (subType == 1)
{
return DBColumnType.Decimal;
}
if (scale < 0)
{
return DBColumnType.Decimal;
}
return DBColumnType.Int64;
case 10:
return DBColumnType.Single;
case 11:
case 0x1b:
return DBColumnType.Double;
case 14:
case 15:
return size == 1 ? DBColumnType.Char : DBColumnType.String;
case 0x0c:
case 0x23:
return DBColumnType.DateTime;
case 0x25:
case 0x26:
return DBColumnType.String;
case 40:
case 0x29:
return DBColumnType.String;
case 0x105:
if (subType == 1)
{
return DBColumnType.String;
}
return DBColumnType.ByteArray;
}
return DBColumnType.Unknown;
}
short GetValue(object value)
{
return value is DBNull ? (short)0 : (short)value;
}
void GetColumns(DBTable table)
{
foreach (SelectStatementResultRow row in SelectData(new Query(string.Format(CultureInfo.InvariantCulture, "select r.RDB$FIELD_NAME, f.RDB$FIELD_TYPE, f.RDB$FIELD_SUB_TYPE, f.RDB$FIELD_SCALE, RDB$CHARACTER_LENGTH from RDB$RELATION_FIELDS r join RDB$FIELDS f on r.RDB$FIELD_SOURCE = f.RDB$FIELD_NAME where r.RDB$RELATION_NAME = '{0}'", ComposeSafeTableName(table.Name)))).Rows)
{
DBColumnType type = GetTypeFromString(GetValue(row.Values[1]), GetValue(row.Values[2]), GetValue(row.Values[3]), GetValue(row.Values[4]));
table.AddColumn(new DBColumn(((string)row.Values[0]).Trim(), false, String.Empty, type == DBColumnType.String ? GetValue(row.Values[4]) : (short)0, type));
}
}
void GetPrimaryKey(DBTable table)
{
SelectStatementResult data = SelectData(new Query(string.Format(CultureInfo.InvariantCulture, "select RDB$INDEX_SEGMENTS.RDB$FIELD_NAME from RDB$RELATION_CONSTRAINTS join RDB$INDEX_SEGMENTS on RDB$INDEX_SEGMENTS.RDB$INDEX_NAME = RDB$RELATION_CONSTRAINTS.RDB$INDEX_NAME where RDB$RELATION_NAME = '{0}' and RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' order by RDB$INDEX_SEGMENTS.RDB$FIELD_POSITION", ComposeSafeTableName(table.Name))));
if (data.Rows.Length > 0)
{
StringCollection cols = new StringCollection();
for (int i = 0; i < data.Rows.Length; i++)
{
object[] topRow = data.Rows[i].Values;
string columnName = ((string)topRow[0]).Trim();
DBColumn column = table.GetColumn(columnName);
if (column != null)
column.IsKey = true;
cols.Add(columnName);
}
table.PrimaryKey = new DBPrimaryKey(cols);
}
}
public override void CreateIndex(DBTable table, DBIndex index)
{
if (table.Name != "XPObjectType")
base.CreateIndex(table, index);
}
void GetIndexes(DBTable table)
{
SelectStatementResult data = SelectData(new Query(string.Format(CultureInfo.InvariantCulture, "select RDB$INDICES.RDB$INDEX_NAME, RDB$INDEX_SEGMENTS.RDB$FIELD_NAME, RDB$INDEX_SEGMENTS.RDB$FIELD_POSITION, RDB$INDICES.RDB$UNIQUE_FLAG from RDB$INDICES join RDB$INDEX_SEGMENTS on RDB$INDEX_SEGMENTS.RDB$INDEX_NAME = RDB$INDICES.RDB$INDEX_NAME where RDB$INDICES.RDB$RELATION_NAME = '{0}' and RDB$INDICES.RDB$FOREIGN_KEY is NULL order by RDB$INDICES.RDB$INDEX_NAME, RDB$INDEX_SEGMENTS.RDB$FIELD_POSITION", ComposeSafeTableName(table.Name))));
DBIndex index = null;
foreach (SelectStatementResultRow row in data.Rows)
{
if (0 == (short)row.Values[2])
{
StringCollection list = new StringCollection();
list.Add(((string)row.Values[1]).Trim());
object isUnique = row.Values[3];
index = new DBIndex(((string)row.Values[0]).Trim(), list, isUnique is short ? (short)isUnique == 1 : false);
table.Indexes.Add(index);
}
else
index.Columns.Add(((string)row.Values[1]).Trim());
}
}
void GetForeignKeys(DBTable table)
{
SelectStatementResult data = SelectData(new Query(string.Format(CultureInfo.InvariantCulture,
@"select p.RDB$FIELD_POSITION, p.RDB$FIELD_NAME, f.RDB$FIELD_NAME, pt.RDB$RELATION_NAME
from RDB$INDICES i
join RDB$INDEX_SEGMENTS f on f.RDB$INDEX_NAME = i.RDB$INDEX_NAME
join RDB$INDEX_SEGMENTS p on p.RDB$INDEX_NAME = i.RDB$FOREIGN_KEY and p.RDB$FIELD_POSITION = f.RDB$FIELD_POSITION
join RDB$INDICES pt on i.RDB$FOREIGN_KEY = pt.RDB$INDEX_NAME
where i.RDB$RELATION_NAME = '{0}' and i.RDB$FOREIGN_KEY is NOT NULL
order by i.RDB$INDEX_NAME, f.RDB$FIELD_POSITION", ComposeSafeTableName(table.Name))));
DBForeignKey fk = null;
foreach (SelectStatementResultRow row in data.Rows)
{
if ((short)row.Values[0] == 0)
{
StringCollection pkc = new StringCollection();
StringCollection fkc = new StringCollection();
pkc.Add(((string)row.Values[2]).Trim());
fkc.Add(((string)row.Values[1]).Trim());
fk = new DBForeignKey(pkc, ((string)row.Values[3]).Trim(), fkc);
table.ForeignKeys.Add(fk);
}
else
{
fk.Columns.Add(((string)row.Values[2]).Trim());
fk.PrimaryKeyTableKeyColumns.Add(((string)row.Values[1]).Trim());
}
}
}
public override void CreateTable(DBTable table)
{
base.CreateTable(table);
if (table.PrimaryKey != null)
{
DBColumn key = table.GetColumn(table.PrimaryKey.Columns[0]);
if (key.IsIdentity)
{
ExecSql(new Query(String.Format(CultureInfo.InvariantCulture, "create generator \"{0}\"", GetSeqName(table.Name))));
}
}
}
public override void GetTableSchema(DBTable table, bool checkIndexes, bool checkForeignKeys)
{
GetColumns(table);
GetPrimaryKey(table);
if (checkIndexes)
GetIndexes(table);
if (checkForeignKeys)
GetForeignKeys(table);
}
public override ICollection CollectTablesToCreate(ICollection tables)
{
Hashtable dbTables = new Hashtable();
foreach (SelectStatementResultRow row in GetDataForTables(tables, null, "select RDB$RELATION_NAME, RDB$VIEW_BLR from RDB$RELATIONS where RDB$RELATION_NAME in ({0}) and RDB$SYSTEM_FLAG = 0").Rows)
dbTables.Add(((string)row.Values[0]).Trim(), row.Values[1] != System.DBNull.Value);
ArrayList list = new ArrayList();
foreach (DBTable table in tables)
{
object o = dbTables[ComposeSafeTableName(table.Name)];
if (o == null)
list.Add(table);
else
table.IsView = (bool)o;
}
return list;
}
protected override int GetSafeNameTableMaxLength()
{
return 31;
}
protected override int GetObjectNameEffectiveLength(string objectName)
{
return Encoding.UTF8.GetByteCount(objectName);
}
public override string FormatTable(string schema, string tableName)
{
return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", tableName);
}
public override string FormatTable(string schema, string tableName, string tableAlias)
{
return string.Format(CultureInfo.InvariantCulture, "\"{0}\" {1}", tableName, tableAlias);
}
public override string FormatColumn(string columnName)
{
return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", columnName);
}
public override string FormatColumn(string columnName, string tableAlias)
{
return string.Format(CultureInfo.InvariantCulture, "{1}.\"{0}\"", columnName, tableAlias);
}
public override string FormatSelect(string selectedPropertiesSql, string fromSql, string whereSql, string orderBySql, string groupBySql, string havingSql, int skipSelectedRecords, int topSelectedRecords)
{
base.FormatSelect(selectedPropertiesSql, fromSql, whereSql, orderBySql, groupBySql, havingSql, skipSelectedRecords, topSelectedRecords);
string topSql = topSelectedRecords != 0 ? string.Format(" first {0} ", topSelectedRecords) : string.Empty;
string skipSql = skipSelectedRecords != 0 ? string.Format(" skip {0} ", skipSelectedRecords) : string.Empty;
string modificatorsSql = string.Format("{0}{1}", topSql, skipSql);
string expandedWhereSql = whereSql != null ? string.Format(CultureInfo.InvariantCulture, "{0}where {1}", Environment.NewLine, whereSql) : string.Empty;
string expandedOrderBySql = orderBySql != null ? string.Format(CultureInfo.InvariantCulture, "{0}order by {1}", Environment.NewLine, orderBySql) : string.Empty;
string expandedHavingSql = havingSql != null ? string.Format(CultureInfo.InvariantCulture, "{0}having {1}", Environment.NewLine, havingSql) : string.Empty;
string expandedGroupBySql = groupBySql != null ? string.Format(CultureInfo.InvariantCulture, "{0}group by {1}", Environment.NewLine, groupBySql) : string.Empty;
return string.Format(CultureInfo.InvariantCulture, "select {0}{1} from {2}{3}{4}{5}{6}", modificatorsSql, selectedPropertiesSql, fromSql, expandedWhereSql, expandedGroupBySql, expandedHavingSql, expandedOrderBySql);
}
public override string FormatOrder(string sortProperty, SortingDirection direction)
{
return string.Format(CultureInfo.InvariantCulture, "{0} {1}", sortProperty, direction == SortingDirection.Ascending ? "asc nulls first" : "desc nulls last");
}
public override bool NativeSkipTakeSupported { get { return true; } }
public override string FormatInsertDefaultValues(string tableName)
{
return string.Format(CultureInfo.InvariantCulture, "insert into {0} values()", tableName);
}
public override string FormatInsert(string tableName, string fields, string values)
{
return string.Format(CultureInfo.InvariantCulture, "insert into {0}({1})values({2})",
tableName, fields, values);
}
public override string FormatUpdate(string tableName, string sets, string whereClause)
{
return string.Format(CultureInfo.InvariantCulture, "update {0} set {1} where {2}",
tableName, sets, whereClause);
}
public override string FormatDelete(string tableName, string whereClause)
{
return string.Format(CultureInfo.InvariantCulture, "delete from {0} where {1}", tableName, whereClause);
}
public override string FormatBinary(BinaryOperatorType operatorType, string leftOperand, string rightOperand)
{
switch (operatorType)
{
case BinaryOperatorType.Modulo:
return string.Format(CultureInfo.InvariantCulture, "mod({0}, {1})", leftOperand, rightOperand);
case BinaryOperatorType.BitwiseXor:
return string.Format(CultureInfo.InvariantCulture, "bin_xor({0}, {1})", leftOperand, rightOperand);
case BinaryOperatorType.BitwiseAnd:
return string.Format(CultureInfo.InvariantCulture, "bin_and({0}, {1})", leftOperand, rightOperand);
case BinaryOperatorType.BitwiseOr:
return string.Format(CultureInfo.InvariantCulture, "bin_or({0}, {1})", leftOperand, rightOperand);
default:
return base.FormatBinary(operatorType, leftOperand, rightOperand);
}
}
string GetFunctionStrLenName()
{
return SupportVersion(2.1m, 0) ? "CHAR_LENGTH" : "strlen";
}
public override string FormatFunction(FunctionOperatorType operatorType, params string[] operands)
{
for (int i = 0; i < operands.Length; i++)
{
operands[i] = DecodeStrParam(operands[i]);
}
switch (operatorType)
{
case FunctionOperatorType.IsNull:
switch (operands.Length)
{
case 1:
return string.Format(CultureInfo.InvariantCulture, "(({0}) is null)", operands[0]);
case 2:
return string.Format(CultureInfo.InvariantCulture, "COALESCE({0}, {1})", operands[0], operands[1]);
}
goto default;
case FunctionOperatorType.IsNullOrEmpty:
return string.Format(CultureInfo.InvariantCulture, "(({0}) is null or ({0}) = '')", operands[0]);
case FunctionOperatorType.Sqr:
return string.Format(CultureInfo.InvariantCulture, "Sqrt({0})", operands[0]);
case FunctionOperatorType.Log:
return FnLog(operands);
case FunctionOperatorType.Log10:
return string.Format(CultureInfo.InvariantCulture, "log(10, {0})", operands[0]);
case FunctionOperatorType.Acos:
return string.Format(CultureInfo.InvariantCulture, "acos({0})", operands[0]);
case FunctionOperatorType.Asin:
return string.Format(CultureInfo.InvariantCulture, "asin({0})", operands[0]);
case FunctionOperatorType.Atn:
return string.Format(CultureInfo.InvariantCulture, "atan({0})", operands[0]);
case FunctionOperatorType.Atn2:
return string.Format(CultureInfo.InvariantCulture, "atan2({0}, {1})", operands[0], operands[1]);
case FunctionOperatorType.Cosh:
return string.Format(CultureInfo.InvariantCulture, "cosh({0})", operands[0]);
case FunctionOperatorType.Sinh:
return string.Format(CultureInfo.InvariantCulture, "sinh({0})", operands[0]);
case FunctionOperatorType.Tanh:
return string.Format(CultureInfo.InvariantCulture, "tanh({0})", operands[0]);
case FunctionOperatorType.Max:
return string.Format(CultureInfo.InvariantCulture, "iif({0} > {1}, {0}, {1})", operands[0], operands[1]);
case FunctionOperatorType.Min:
return string.Format(CultureInfo.InvariantCulture, "iif({0} < {1}, {0}, {1})", operands[0], operands[1]);
case FunctionOperatorType.Rnd:
return "Rand()";
case FunctionOperatorType.BigMul:
return string.Format(CultureInfo.InvariantCulture, "(cast({0} as bigint) * cast({1} as bigint))", operands[0], operands[1]);
case FunctionOperatorType.GetMilliSecond:
return string.Format(CultureInfo.InvariantCulture, "(cast(extract(second from {0}) - floor(extract(second from {0})) as numeric(4, 4)) * 1000)", operands[0]);
case FunctionOperatorType.GetSecond:
return string.Format(CultureInfo.InvariantCulture, "floor(extract(second from {0}))", operands[0]);
case FunctionOperatorType.GetMinute:
return string.Format(CultureInfo.InvariantCulture, "extract(minute from {0})", operands[0]);
case FunctionOperatorType.GetHour:
return string.Format(CultureInfo.InvariantCulture, "extract(hour from {0})", operands[0]);
case FunctionOperatorType.GetDay:
return string.Format(CultureInfo.InvariantCulture, "extract(day from {0})", operands[0]);
case FunctionOperatorType.GetMonth:
return string.Format(CultureInfo.InvariantCulture, "extract(month from {0})", operands[0]);
case FunctionOperatorType.GetYear:
return string.Format(CultureInfo.InvariantCulture, "extract(year from {0})", operands[0]);
case FunctionOperatorType.GetTimeOfDay:
return string.Format(CultureInfo.InvariantCulture, "floor(extract(hour from {0}) * 36000000000 + extract(minute from {0}) * 600000000 + extract(second from {0}) * 10000000)", operands[0]);
case FunctionOperatorType.GetDayOfWeek:
return string.Format(CultureInfo.InvariantCulture, "extract(weekday from {0})", operands[0]);
case FunctionOperatorType.GetDayOfYear:
return string.Format(CultureInfo.InvariantCulture, "(extract(yearday from {0}) + 1)", operands[0]);
case FunctionOperatorType.GetDate:
return string.Format(CultureInfo.InvariantCulture, "cast(cast({0} as date) as timestamp)", operands[0]);
case FunctionOperatorType.Ascii:
return string.Format(CultureInfo.InvariantCulture, "ascii_val(substring(cast({0} as varchar(10921)) from 1 for 1))", operands[0]);
case FunctionOperatorType.Char:
return string.Format(CultureInfo.InvariantCulture, "ascii_char({0})", operands[0]);
case FunctionOperatorType.ToInt:
return string.Format(CultureInfo.InvariantCulture, "cast({0} as integer)", operands[0]);
case FunctionOperatorType.ToLong:
return string.Format(CultureInfo.InvariantCulture, "cast({0} as bigint)", operands[0]);
case FunctionOperatorType.ToFloat:
return string.Format(CultureInfo.InvariantCulture, "cast({0} as float)", operands[0]);
case FunctionOperatorType.ToDouble:
return string.Format(CultureInfo.InvariantCulture, "cast({0} as double precision)", operands[0]);
case FunctionOperatorType.ToDecimal:
return string.Format(CultureInfo.InvariantCulture, "cast({0} as decimal(18,4))", operands[0]);
case FunctionOperatorType.ToStr:
return string.Format(CultureInfo.InvariantCulture, "cast({0} as varchar(10921))", operands[0]);
case FunctionOperatorType.Len:
return string.Format(CultureInfo.InvariantCulture, GetFunctionStrLenName() + "(trim({0}))", operands[0]);
case FunctionOperatorType.Trim:
return string.Format(CultureInfo.InvariantCulture, "trim({0})", operands[0]);
case FunctionOperatorType.PadLeft:
return FnLpad(operands);
case FunctionOperatorType.PadRight:
return FnRpad(operands);
case FunctionOperatorType.AddTicks:
return string.Format(CultureInfo.InvariantCulture, "({0} + cast({1} as double precision) / cast(864000000000 as double precision))", operands[0], operands[1]);
case FunctionOperatorType.AddMilliSeconds:
return string.Format(CultureInfo.InvariantCulture, "({0} + cast({1} as double precision) / cast(86400000 as double precision))", operands[0], operands[1]);
case FunctionOperatorType.AddTimeSpan:
case FunctionOperatorType.AddSeconds:
return string.Format(CultureInfo.InvariantCulture, "({0} + cast({1} as double precision) / cast(86400 as double precision))", operands[0], operands[1]);
case FunctionOperatorType.AddMinutes:
return string.Format(CultureInfo.InvariantCulture, "({0} + cast({1} as double precision) / cast(1440 as double precision))", operands[0], operands[1]);
case FunctionOperatorType.AddHours:
return string.Format(CultureInfo.InvariantCulture, "({0} + cast({1} as double precision) / cast(24 as double precision))", operands[0], operands[1]);
case FunctionOperatorType.AddDays:
return string.Format(CultureInfo.InvariantCulture, "({0} + cast({1} as double precision))", operands[0], operands[1]);
case FunctionOperatorType.Now:
return "cast('now' as timestamp)";
case FunctionOperatorType.Today:
return "cast('today' as timestamp)";
case FunctionOperatorType.Concat:
string args = String.Empty;
for (int i = 0; i < operands.Length; i++)
{
if (operands[i].Length > 0)
args += i == operands.Length - 1 ? string.Format(CultureInfo.InvariantCulture, "{0}", operands[i]) : string.Format(CultureInfo.InvariantCulture, "{0} || ", operands[i]);
}
return args;
case FunctionOperatorType.DateDiffDay:
return string.Format(CultureInfo.InvariantCulture, "datediff(day, {0}, {1})", operands[0], operands[1]);
case FunctionOperatorType.DateDiffHour:
return string.Format(CultureInfo.InvariantCulture, "datediff(hour, {0}, {1})", operands[0], operands[1]);
case FunctionOperatorType.DateDiffMilliSecond:
return string.Format(CultureInfo.InvariantCulture, "datediff(millisecond, {0}, {1})", operands[0], operands[1]);
case FunctionOperatorType.DateDiffMinute:
return string.Format(CultureInfo.InvariantCulture, "datediff(minute, {0}, {1})", operands[0], operands[1]);
case FunctionOperatorType.DateDiffMonth:
return string.Format(CultureInfo.InvariantCulture, "datediff(month, {0}, {1})", operands[0], operands[1]);
case FunctionOperatorType.DateDiffSecond:
return string.Format(CultureInfo.InvariantCulture, "datediff(second, {0}, {1})", operands[0], operands[1]);
case FunctionOperatorType.DateDiffYear:
return string.Format(CultureInfo.InvariantCulture, "datediff(year, {0}, {1})", operands[0], operands[1]);
case FunctionOperatorType.AddMonths:
case FunctionOperatorType.AddYears:
case FunctionOperatorType.Exp:
case FunctionOperatorType.Power:
case FunctionOperatorType.Round:
case FunctionOperatorType.Substring:
case FunctionOperatorType.Insert:
case FunctionOperatorType.Remove:
case FunctionOperatorType.CharIndex:
case FunctionOperatorType.UtcNow:
throw new NotSupportedException();
default:
return base.FormatFunction(operatorType, operands);
}
}
readonly static char[] achtungChars = new char[] { '_', '%' };
public override string FormatFunction(ProcessParameter processParameter, FunctionOperatorType operatorType, params object[] operands)
{
switch (operatorType)
{
case FunctionOperatorType.StartsWith:
case FunctionOperatorType.EndsWith:
case FunctionOperatorType.Contains:
object secondOperand = operands[1];
if (secondOperand is OperandValue && ((OperandValue)secondOperand).Value is string)
{
string operandString = (string)((OperandValue)secondOperand).Value;
bool needEscape = operandString.IndexOfAny(achtungChars) >= 0;
if (needEscape)
operandString = operandString.Replace("\\", "\\\\").Replace("%", "\\%").Replace("_", "\\_");
string operandStringFormatted;
switch (operatorType)
{
case FunctionOperatorType.StartsWith:
operandStringFormatted = processParameter(new ConstantValue(operandString + "%"));
break;
case FunctionOperatorType.EndsWith:
operandStringFormatted = processParameter(new ConstantValue("%" + operandString));
break;
case FunctionOperatorType.Contains:
operandStringFormatted = processParameter(new ConstantValue(string.Concat("%", operandString, "%")));
break;
default:
throw new NotSupportedException();
}
if (needEscape)
{
return string.Format(CultureInfo.InvariantCulture, @"({0} like {1} ESCAPE '\')", processParameter(operands[0]), operandStringFormatted);
}
return string.Format(CultureInfo.InvariantCulture, "({0} like {1})", processParameter(operands[0]), operandStringFormatted);
}
throw new NotSupportedException();
default:
return base.FormatFunction(processParameter, operatorType, operands);
}
}
string FnLog(string[] operands)
{
if (operands.Length == 1)
{
return string.Format(CultureInfo.InvariantCulture, "Ln({0})", operands[0]);
}
if (operands.Length == 2)
{
return string.Format(CultureInfo.InvariantCulture, "log({1}, {0})", operands[0], operands[1]);
}
throw new NotSupportedException();
}
string FnLpad(string[] operands)
{
if (operands.Length == 2)
{
return string.Format(CultureInfo.InvariantCulture, "iif({2}({0}) > {1}, {0}, lpad({0}, {1}, ' '))", operands[0], operands[1], GetFunctionStrLenName());
}
if (operands.Length == 3)
{
return string.Format(CultureInfo.InvariantCulture, "iif({3}({0}) > {1}, {0}, lpad({0}, {1}, {2}))", operands[0], operands[1], operands[2], GetFunctionStrLenName());
}
throw new NotSupportedException();
}
string FnRpad(string[] operands)
{
if (operands.Length == 2)
{
return string.Format(CultureInfo.InvariantCulture, "iif({2}({0}) > {1}, {0}, rpad({0}, {1}, ' '))", operands[0], operands[1], GetFunctionStrLenName());
}
if (operands.Length == 3)
{
return string.Format(CultureInfo.InvariantCulture, "iif({3}({0}) > {1}, {0}, rpad({0}, {1}, {2}))", operands[0], operands[1], operands[2], GetFunctionStrLenName());
}
throw new NotSupportedException();
}
public override string GetParameterName(OperandValue parameter, int index, ref bool createParameter)
{
object value = parameter.Value;
createParameter = false;
if (parameter is ConstantValue && value != null)
{
switch (Type.GetTypeCode(value.GetType()))
{
case TypeCode.Int32:
return ((int)value).ToString(CultureInfo.InvariantCulture);
case TypeCode.Boolean:
return (bool)value ? "true" : "false";
case TypeCode.String:
return "'" + ((string)value).Replace("'", "''") + "'";
}
}
createParameter = true;
if (parameter.Value is string)
{
return string.Format(CultureInfo.InvariantCulture, "@s{0}_{1}", index, ((string)parameter.Value).Length);
}
return "@p" + index.ToString(CultureInfo.InvariantCulture);
}
static string DecodeStrParam(string operand)
{
if (operand.StartsWith("@s"))
{
int strLen = int.Parse(operand.Substring(operand.IndexOf('_') + 1));
return string.Format(CultureInfo.InvariantCulture, "cast({0} as varchar({1}))", operand, strLen);
}
return operand;
}
public override bool SupportNamedParameters { get { return true; } }
public override string FormatConstraint(string constraintName)
{
return string.Format(CultureInfo.InvariantCulture, "\"{0}\"", constraintName);
}
protected override string CreateForeignKeyTemplate { get { return base.CreateForeignKeyTemplate; } }
void ClearDatabase(IDbCommand command)
{
SelectStatementResult generators = SelectData(new Query("select RDB$GENERATOR_NAME from RDB$GENERATORS where RDB$SYSTEM_FLAG is null or RDB$SYSTEM_FLAG = 0"));
foreach (SelectStatementResultRow row in generators.Rows)
{
command.CommandText = "drop generator \"" + ((string)row.Values[0]).Trim() + "\"";
command.ExecuteNonQuery();
}
SelectStatementResult constraints = SelectData(new Query("select RDB$CONSTRAINT_NAME, RDB$RELATION_NAME from RDB$RELATION_CONSTRAINTS where RDB$CONSTRAINT_TYPE = 'FOREIGN KEY' "));
foreach (SelectStatementResultRow row in constraints.Rows)
{
command.CommandText = "alter table \"" + ((string)row.Values[1]).Trim() + "\" drop constraint \"" + ((string)row.Values[0]).Trim() + "\"";
command.ExecuteNonQuery();
}
string[] tables = GetStorageTablesList(false);
foreach (string table in tables)
{
command.CommandText = "drop table \"" + table + "\"";
command.ExecuteNonQuery();
}
}
protected override void ProcessClearDatabase()
{
IDbCommand command = CreateCommand();
ClearDatabase(command);
}
protected override SelectedData ExecuteSprocParametrized(string sprocName, params OperandValue[] parameters)
{
throw new NotSupportedException();
}
public override string[] GetStorageTablesList(bool includeViews)
{
SelectStatementResult tables = SelectData(new Query("select RDB$RELATION_NAME, RDB$VIEW_BLR from RDB$RELATIONS where RDB$SYSTEM_FLAG = 0"));
List<string> result = new List<string>(tables.Rows.Length);
for (int i = 0; i < tables.Rows.Length; i++)
{
if (!includeViews && tables.Rows[i].Values[1] != DBNull.Value && tables.Rows[i].Values[1] != null)
continue;
result.Add(((string)tables.Rows[i].Values[0]).TrimEnd());
}
return result.ToArray();
}
ExecMethodDelegate commandBuilderDeriveParametersHandler;
protected override void CommandBuilderDeriveParameters(IDbCommand command)
{
if (commandBuilderDeriveParametersHandler == null)
{
commandBuilderDeriveParametersHandler = ReflectConnectionHelper.GetCommandBuilderDeriveParametersDelegate("FirebirdSql.Data.FirebirdClient", "FirebirdSql.Data.FirebirdClient.FbCommandBuilder");
}
commandBuilderDeriveParametersHandler(command);
}
public override DBStoredProcedure[] GetStoredProcedures()
{
List<DBStoredProcedure> result = new List<DBStoredProcedure>();
using (var command = Connection.CreateCommand())
{
command.CommandText = "SELECT rdb$procedure_name FROM rdb$procedures ORDER BY rdb$procedure_name";
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
DBStoredProcedure curProc = new DBStoredProcedure();
string procName = reader.GetString(0);
if (string.IsNullOrEmpty(procName))
{
continue;
}
curProc.Name = procName.Trim();
result.Add(curProc);
}
}
}
foreach (DBStoredProcedure sproc in result)
{
using (var command = Connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = FormatTable(ComposeSafeSchemaName(sproc.Name), ComposeSafeTableName(sproc.Name));
CommandBuilderDeriveParameters(command);
List<DBStoredProcedureArgument> dbArguments = new List<DBStoredProcedureArgument>();
foreach (IDataParameter parameter in command.Parameters)
{
DBStoredProcedureArgumentDirection direction = DBStoredProcedureArgumentDirection.In;
if (parameter.Direction == ParameterDirection.InputOutput)
{
direction = DBStoredProcedureArgumentDirection.InOut;
}
if (parameter.Direction == ParameterDirection.Output)
{
direction = DBStoredProcedureArgumentDirection.Out;
}
DBColumnType columnType = GetColumnType(parameter.DbType, true);
dbArguments.Add(new DBStoredProcedureArgument(parameter.ParameterName, columnType, direction));
}
sproc.Arguments.AddRange(dbArguments);
}
}
return result.ToArray();
}
}
public class FirebirdProviderFactory : ProviderFactory
{
public override IDataStore CreateProviderFromConnection(IDbConnection connection, AutoCreateOption autoCreateOption)
{
return Firebird3ConnectionProvider.CreateProviderFromConnection(connection, autoCreateOption);
}
public override IDataStore CreateProviderFromString(string connectionString, AutoCreateOption autoCreateOption, out IDisposable[] objectsToDisposeOnDisconnect)
{
return Firebird3ConnectionProvider.CreateProviderFromString(connectionString, autoCreateOption, out objectsToDisposeOnDisconnect);
}
public override string GetConnectionString(Dictionary<string, string> parameters)
{
if ((!parameters.ContainsKey(ServerParamID) && !parameters.ContainsKey(DatabaseParamID)) ||
!parameters.ContainsKey(UserIDParamID) || !parameters.ContainsKey(PasswordParamID))
{
return null;
}
string connectionString = "";
if (parameters.ContainsKey(ServerParamID))
{
connectionString = Firebird3ConnectionProvider.GetConnectionString(parameters[ServerParamID], parameters[UserIDParamID],
parameters[PasswordParamID], parameters[DatabaseParamID]);
}
else
{
connectionString = Firebird3ConnectionProvider.GetConnectionString(parameters[UserIDParamID],
parameters[PasswordParamID], parameters[DatabaseParamID]);
}
return connectionString;
}
public override IDataStore CreateProvider(Dictionary<string, string> parameters, AutoCreateOption autoCreateOption, out IDisposable[] objectsToDisposeOnDisconnect)
{
string connectionString = GetConnectionString(parameters);
if (connectionString == null)
{
objectsToDisposeOnDisconnect = new IDisposable[0];
return null;
}
ConnectionStringParser helper = new ConnectionStringParser(connectionString);
helper.RemovePartByName(DataStoreBase.XpoProviderTypeParameterName);
return CreateProviderFromString(helper.GetConnectionString(), autoCreateOption, out objectsToDisposeOnDisconnect);
}
public override bool HasUserName { get { return true; } }
public override bool HasPassword { get { return true; } }
public override bool HasIntegratedSecurity { get { return false; } }
public override bool HasMultipleDatabases { get { return true; } }
public override bool IsServerbased { get { return true; } }
public override bool IsFilebased { get { return true; } }
public override string ProviderKey { get { return Firebird3ConnectionProvider.XpoProviderTypeString; } }
public override string[] GetDatabases(string server, string userid, string password)
{
return new string[0];
}
public override string FileFilter { get { return "Firebird databases|*.gdb;*.fdb"; } }
public override bool MeanSchemaGeneration { get { return true; } }
}
}
以上是关于csharp #fire #xaf的#firebird连接提供程序的主要内容,如果未能解决你的问题,请参考以下文章
csharp #xaf #controller #ShowCustomStartupNavigationItemController
csharp #xaf #pictureedit #zooming
csharp #xaf #lisview #viewController