📄 fastdbfields.cs
字号:
break; case CLI.FieldType.cli_real4: *(Single*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer() = Convert.ToSingle(Value); break; case CLI.FieldType.cli_datetime: case CLI.FieldType.cli_real8: *(double*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer() = Convert.ToDouble(Value); break; case CLI.FieldType.cli_asciiz: case CLI.FieldType.cli_pasciiz: //byte[] bytes = Encoding.Convert(Encoding.Unicode, Encoding.ASCII, Encoding.Unicode.GetBytes(Value.ToString())); //cli_ex_buffer_resize(buffer, buffer.type, bytes.Length, true); //buffer.data = Marshal.AllocCoTaskMem( bytes.Length ); //Marshal. //Marshal.Copy(bytes, 0, buffer.data, bytes.Length); //fixed(char* p = &bytes[0]) //{ string s = Value.ToString(); IntPtr str = Marshal.StringToHGlobalAnsi(s); try { CopyBufferData((CLI.FieldType)((CLI.UnmanagedBuffer*)buffer.ToPointer())->type, s.Length, str); } finally { Marshal.FreeCoTaskMem(str); } break; default: throw new CliError("Unsupported type: "+Enum.GetName(typeof(CLI.FieldType), (CLI.FieldType)((CLI.UnmanagedBuffer*)buffer.ToPointer())->type)); } } // Implement IDisposable. // This method is not virtual. A derived class should not be able to override this method. public void Dispose() { Dispose(true); // Take yourself off the Finalization queue // to prevent finalization code for this object // from executing a second time. GC.SuppressFinalize(this); } // Dispose(bool disposing) executes in two distinct scenarios. // If disposing equals true, the method has been called directly // or indirectly by a user's code. Managed and unmanaged resources // can be disposed. // If disposing equals false, the method has been called by the // runtime from inside the finalizer and you should not reference // other objects. Only unmanaged resources can be disposed. protected unsafe virtual void Dispose(bool disposing) { // Check to see if Dispose has already been called. if(!this.disposed) { // If disposing equals true, dispose managed resources. if(disposing) { // Dispose managed resources here. Marshal.FreeCoTaskMem(((CLI.UnmanagedBuffer*)buffer.ToPointer())->data); ((CLI.UnmanagedBuffer*)buffer.ToPointer())->data = (IntPtr)0; Marshal.FreeCoTaskMem(buffer); } // Release unmanaged resources. //CLI.cli_ex_buffer_free(buffer); disposed = true; } } #region IEnumerable Members public IEnumerator GetEnumerator() { // TODO: Add FastDbBuffer.GetEnumerator implementation return null; } #endregion } //------------------------------------------------------------------------- /// <summary> /// FastDbField implements a class that automatically manages the memory /// associated with a field belonging to a database cursor. /// </summary> public class FastDbField: FastDbBuffer { public string RefTable; public string InvRefField; /// <summary> /// Field's constructor. /// </summary> /// <param name="name">Field name</param> /// <param name="field_type">Field type</param> /// <param name="idx_flags">Index types (hash/T-tree)</param> /// <param name="ref_table">Reference table name for inverse reference fields</param> /// <param name="inv_ref_field">Inverse reference field name</param> public FastDbField(string name, CLI.FieldType field_type, CLI.FieldFlags idx_flags, string ref_table, string inv_ref_field) : base(name, field_type, idx_flags) { this.RefTable = ref_table; this.InvRefField = inv_ref_field; } /// <summary> /// Copy field's content to the current field /// </summary> /// <param name="field">Source field to copy from</param> public override void Assign(FastDbBuffer field) { Debug.Assert(field is FastDbField, "Cannot assign " + field.GetType().Name + " type!"); base.Assign(field); this.RefTable = ((FastDbField)field).RefTable; this.InvRefField = ((FastDbField)field).InvRefField; } /// <summary> /// Is true if the field is of array type. /// </summary> public bool IsArray { get { return CLI.IsArrayType(Type); } } /// <summary> /// Returns the number of array elements for array type fields /// </summary> public unsafe int ArraySize { get { if (CLI.IsArrayType(this.Type)) { return Size / CLI.SizeOfCliType[(int)this.Type - (int)CLI.FieldType.cli_array_of_oid]; } else return 0; } set { Debug.Assert(CLI.IsArrayType(this.Type), "Cannot set array size on non-array fields: "+Enum.GetName(typeof(CLI.FieldType), Type)); int n = CLI.SizeOfCliType[(int)this.Type - (int)CLI.FieldType.cli_array_of_oid] * value; if (Size != n) SetBufferTypeAndSize((CLI.UnmanagedBuffer*)buffer.ToPointer(), this.Type, n, true); } } public bool ArrayAsBoolean(int idx) { return (bool)getArrayValue(typeof(bool), idx);} public Int16 ArrayAsInt16(int idx) { return (Int16)getArrayValue(typeof(Int16), idx);} public uint ArrayAsOID(int idx) { return (uint)getArrayValue(typeof(uint), idx);} public Int64 ArrayAsInt64(int idx) { return (Int64)getArrayValue(typeof(Int64), idx);} public double ArrayAsDouble(int idx) { return (double)getArrayValue(typeof(double), idx);} public string ArrayAsString(int idx) { return (string)getArrayValue(typeof(string), idx);} protected unsafe Object getArrayValue(Type t, int idx) { switch((CLI.FieldType)((CLI.UnmanagedBuffer*)buffer.ToPointer())->type) { case CLI.FieldType.cli_array_of_bool: case CLI.FieldType.cli_array_of_int1: return Convert.ChangeType(*((sbyte*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(sbyte)*idx), t); case CLI.FieldType.cli_array_of_int2: return Convert.ChangeType(*((short*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(short)*idx), t); case CLI.FieldType.cli_array_of_oid: return Convert.ChangeType(*((uint*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(uint)*idx), t); case CLI.FieldType.cli_array_of_int4: return Convert.ChangeType(*((int*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(int)*idx), t); case CLI.FieldType.cli_array_of_int8: return Convert.ChangeType(*((Int64*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(Int64)*idx), t); case CLI.FieldType.cli_array_of_real4: return Convert.ChangeType(*((Single*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(Single)*idx), t); case CLI.FieldType.cli_array_of_real8: return Convert.ChangeType(*((double*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(double)*idx), t); default: throw new CliError("Unsupported type!"); } } /// <summary> /// This method adds functionality to the base class that allows to get /// the content of an array field as string. /// </summary> /// <param name="t"></param> /// <returns></returns> protected override unsafe Object getValue(Type t) { switch((CLI.FieldType)((CLI.UnmanagedBuffer*)buffer.ToPointer())->type) { case CLI.FieldType.cli_array_of_int1: case CLI.FieldType.cli_array_of_int2: case CLI.FieldType.cli_array_of_int4: case CLI.FieldType.cli_array_of_int8: case CLI.FieldType.cli_array_of_oid: case CLI.FieldType.cli_array_of_real4: case CLI.FieldType.cli_array_of_real8: if (t != typeof(string)) throw new CliError("getValue: Unsupported conversion type! "+Enum.GetName(typeof(CLI.FieldType), ((CLI.UnmanagedBuffer*)buffer.ToPointer())->type)); StringBuilder s = new StringBuilder("{"); for(int i=0; i < ArraySize; i++) { s.Append(ArrayAsString(i)); s.Append( (i == ArraySize-1) ? "" : "," ); } s.Append("}"); return s.ToString(); default: return base.getValue(t); } } /// <summary> /// Set a value of an array element. <seealso cref="CLI.FieldType"/> /// </summary> /// <param name="idx">Element index</param> /// <param name="Value">Element's new value</param> public unsafe void SetArrayValue(int idx, Object Value) { Debug.Assert(idx >= 0 && idx < ArraySize, "Array index " + idx + " out of bounds!"); switch((CLI.FieldType)((CLI.UnmanagedBuffer*)buffer.ToPointer())->type) { case CLI.FieldType.cli_array_of_oid: *((uint*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(uint)*idx) = Convert.ToUInt32(Value); break; case CLI.FieldType.cli_array_of_int4: *((int*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(int)*idx) = Convert.ToInt32(Value); break; case CLI.FieldType.cli_array_of_bool: case CLI.FieldType.cli_int1: *((sbyte*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(sbyte)*idx) = Convert.ToSByte(Value); break; case CLI.FieldType.cli_array_of_int2: *((Int16*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(Int16)*idx) = Convert.ToInt16(Value); break; case CLI.FieldType.cli_array_of_int8: *((Int64*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(Int64)*idx) = Convert.ToInt64(Value); break; case CLI.FieldType.cli_array_of_real4: *((Single*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(Single)*idx) = Convert.ToSingle(Value); break; case CLI.FieldType.cli_array_of_real8: *((double*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer()+sizeof(double)*idx) = Convert.ToDouble(Value); break; default: throw new CliError("Unsupported type!"); } } internal unsafe override void Bind(int StatementID) { int res; base.Bind(StatementID); if (bound_to_statement == StatementID) return; else bound_to_statement = StatementID; //IntPtr pname = Marshal.StringToHGlobalAnsi(Name); try { if (CLI.IsArrayType(Type) || Type == CLI.FieldType.cli_asciiz || Type == CLI.FieldType.cli_pasciiz) res = CLI.cli_array_column_ex(StatementID, name, (Type == CLI.FieldType.cli_pasciiz) ? (int)CLI.FieldType.cli_asciiz : (int)Type, ((CLI.UnmanagedBuffer*)buffer.ToPointer())->data, doSetColumn, doGetColumn, (CLI.UnmanagedBuffer*)buffer.ToPointer()); else res = CLI.cli_column(StatementID, name, (int)Type, ref ((CLI.UnmanagedBuffer*)buffer.ToPointer())->size, ((CLI.UnmanagedBuffer*)buffer.ToPointer())->data); CLI.CliCheck(res);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -