⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fastdbfields.cs

📁 最新版本!fastdb是高效的内存数据库系统
💻 CS
📖 第 1 页 / 共 3 页
字号:
          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 + -