AdapterBase

Base class for adapters

Parameters

(None)
(defined in /src/adapters/base.ts:41)
abstract class AdapterBase {
  /**
   * Wraps adapter specific errors
   * @param msg CORMO's error message
   * @param cause adapter specific error object
   * @internal
   */
  public static wrapError(msg: string, cause?: Error): Error {
    if (msg === 'unknown error' && cause && cause.message === 'transaction finished') {
      return cause;
    }
    const error = new Error(msg);
    (error as any).cause = cause;
    return error;
  }

  /** @internal */
  public _connection!: Connection;

  /** @internal */
  public support_fractional_seconds = true;

  /** @internal */
  public support_upsert = true;

  /** @internal */
  public support_nested = false;

  /** @internal */
  public support_geopoint = false;

  /** @internal */
  public support_string_type_with_length = false;

  /** @internal */
  public key_type: any;
  /** @internal */
  public key_type_internal: any;

  /** @internal */
  public native_integrity = false;

  /** @internal */
  public async connect(settings: {}) {
    return;
  }

  /**
   * Returns current schemas.
   * @abstract
   * @see Connection::applySchemas
   * @internal
   */
  public async getSchemas(): Promise<ISchemas> {
    return { tables: {} };
  }

  /**
   * Creates a table.
   * @abstract
   * @see Connection::applySchemas
   * @internal
   */
  public async createTable(model: string) {
    return;
  }

  /** Adds a column to a table
   * @abstract
   * @see Connection::applySchemas
   * @internal
   */
  public async addColumn(model: string, column_property: object) {
    return;
  }

  /** Creates an index.
   * @abstract
   * @see Connection::applySchemas
   * @internal
   */
  public async createIndex(model_name: string, index: IIndexProperty) {
    return;
  }

  /** Creates a foreign key.
   * @abstract
   * @see Connection::applySchemas
   * @internal
   */
  public async createForeignKey(model: string, column: string, type: string, references: {}) {
    return;
  }

  /**
   * Drops a model from the database
   * @abstract
   * @see BaseModel.drop
   * @internal
   */
  public async drop(model: string) {
    throw new Error('not implemented');
  }

  /** @internal */
  public idToDB(value: any) {
    return value;
  }

  /** @internal */
  public valueToDB(value: any, column: any, property: any) {
    if (property.type_class === types.Object || property.array) {
      return JSON.stringify(value);
    } else if (value != null) {
      return value;
    } else {
      return null;
    }
  }

  /** @internal */
  public setValuesFromDB(instance: any, data: any, schema: any, selected_columns: any) {
    if (!selected_columns) {
      selected_columns = Object.keys(schema);
    }
    const support_nested = this.support_nested;
    for (const column of selected_columns) {
      const property = schema[column];
      let value = support_nested ? util.getPropertyOfPath(data, property._parts_db) : data[property._dbname_us];
      if (value != null) {
        value = this.valueToModel(value, property);
      } else {
        value = null;
      }
      util.setPropertyOfPath(instance, property._parts, value);
    }
  }

  /**
   * Creates a record
   * @internal
   */
  public abstract async create(model: string, data: any, options: { transaction?: Transaction }): Promise<any>;

  /**
   * Creates records
   * @internal
   */
  public abstract async createBulk(
    model: string, data: any[],
    options: { transaction?: Transaction },
  ): Promise<any[]>;

  /**
   * Updates a record
   * @internal
   */
  public abstract async update(model: string, data: any, options: { transaction?: Transaction }): Promise<void>;

  /**
   * Updates some fields of records that match conditions
   * @internal
   */
  public abstract async updatePartial(
    model: string, data: any, conditions: any,
    options: { transaction?: Transaction },
  ): Promise<number>;

  /**
   * Updates some fields of records that match conditions or inserts a new record
   * @internal
   */
  public abstract async upsert(model: string, data: any, conditions: any, options: any): Promise<void>;

  /**
   * Finds a record by id
   * @see Query::exec
   * @internal
   */
  public abstract async findById(
    model: string, id: any,
    options: { select?: string[], explain?: boolean, transaction?: Transaction },
  ): Promise<any>;

  /**
   * Finds records
   * @see Query::exec
   * @internal
   */
  public abstract async find(model: string, conditions: any, options: IAdapterFindOptions): Promise<any>;

  /**
   * Streams matching records
   * @see Query::stream
   * @internal
   */
  public abstract stream(model: any, conditions: any, options: IAdapterFindOptions): stream.Readable;

  /**
   * Counts records
   * @see Query::count
   * @internal
   */
  public abstract async count(model: string, conditions: any, options: IAdapterCountOptions): Promise<number>;

  /**
   * Deletes records from the database
   * @see Query::delete
   * @internal
   */
  public abstract async delete(model: string, conditions: any, options: { transaction?: Transaction }): Promise<number>;

  /**
   * Closes connection
   * @internal
   */
  public abstract close(): void;

  /** @internal */
  public async getConnection(): Promise<any> {
    //
  }

  /** @internal */
  public async releaseConnection(adapter_connection: any): Promise<void> {
    //
  }

  /** @internal */
  public async startTransaction(adapter_connection: any, isolation_level?: IsolationLevel): Promise<void> {
    //
  }

  /** @internal */
  public async commitTransaction(adapter_connection: any): Promise<void> {
    //
  }

  /** @internal */
  public async rollbackTransaction(adapter_connection: any): Promise<void> {
    //
  }

  /** @internal */
  protected _getModelID(data: any) {
    return data.id;
  }

  /** @internal */
  protected valueToModel(value: any, property: any) {
    if (property.type_class === types.Object || property.array) {
      return JSON.parse(value);
    } else {
      return value;
    }
  }

  /** @internal */
  protected _convertToModelInstance(model: any, data: any, options: any) {
    if (options.lean) {
      model = this._connection.models[model];
      const instance: any = {};
      this.setValuesFromDB(instance, data, model._schema, options.select);
      model._collapseNestedNulls(instance, options.select_raw, null);
      const id = this._getModelID(data);
      if (id) {
        instance.id = id;
      }
      return instance;
    } else {
      const id = this._getModelID(data);
      const modelClass: any = this._connection.models[model];
      return new modelClass(data, id, options.select, options.select_raw);
    }
  }

  /** @internal */
  protected _convertToGroupInstance(model_name: string, data: any, group_by: any, group_fields: any) {
    const instance: any = {};
    if (group_by) {
      const schema = this._connection.models[model_name]._schema;
      for (const field of group_by) {
        const property = _.find(schema, (item) => item._dbname_us === field);
        if (property) {
          util.setPropertyOfPath(instance, property._parts, this.valueToModel(data[field], property));
        }
      }
    }
    // tslint:disable-next-line:forin
    for (const field in group_fields) {
      const expr = group_fields[field];
      const op = Object.keys(expr)[0];
      if (op === '$sum' || op === '$max' || op === '$min' || op === '$avg') {
        instance[field] = Number(data[field]);
      } else if (op === '$any') {
        instance[field] = data[field];
      }
    }
    return instance;
  }

  /** @internal */
  protected async _createBulkDefault(model: string, data: any[], options: { transaction?: Transaction }) {
    return await Promise.all(data.map((item: any) => {
      return this.create(model, item, options);
    }));
  }
}
(defined in /src/adapters/base.ts:58)
public _connection!: Connection;

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:318)
protected _convertToGroupInstance(model_name: string, data: any, group_by: any, group_fields: any) {
    const instance: any = {};
    if (group_by) {
      const schema = this._connection.models[model_name]._schema;
      for (const field of group_by) {
        const property = _.find(schema, (item) => item._dbname_us === field);
        if (property) {
          util.setPropertyOfPath(instance, property._parts, this.valueToModel(data[field], property));
        }
      }
    }
    // tslint:disable-next-line:forin
    for (const field in group_fields) {
      const expr = group_fields[field];
      const op = Object.keys(expr)[0];
      if (op === '$sum' || op === '$max' || op === '$min' || op === '$avg') {
        instance[field] = Number(data[field]);
      } else if (op === '$any') {
        instance[field] = data[field];
      }
    }
    return instance;
  }

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:299)
protected _convertToModelInstance(model: any, data: any, options: any) {
    if (options.lean) {
      model = this._connection.models[model];
      const instance: any = {};
      this.setValuesFromDB(instance, data, model._schema, options.select);
      model._collapseNestedNulls(instance, options.select_raw, null);
      const id = this._getModelID(data);
      if (id) {
        instance.id = id;
      }
      return instance;
    } else {
      const id = this._getModelID(data);
      const modelClass: any = this._connection.models[model];
      return new modelClass(data, id, options.select, options.select_raw);
    }
  }

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:343)
protected async _createBulkDefault(model: string, data: any[], options: { transaction?: Transaction }) {
    return await Promise.all(data.map((item: any) => {
      return this.create(model, item, options);
    }));
  }

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:285)
protected _getModelID(data: any) {
    return data.id;
  }

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:113)
public async addColumn(model: string, column_property: object) {
    return;
  }

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:257)
public abstract close(): void;

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:275)
public async commitTransaction(adapter_connection: any): Promise<void> {
    //
  }

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:84)
public async connect(settings: {}) {
    return;
  }

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:244)
public abstract async count(model: string, conditions: any, options: IAdapterCountOptions): Promise<number>;

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:183)
public abstract async create(model: string, data: any, options: { transaction?: Transaction }): Promise<any>;

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:189)
public abstract async createBulk(
    model: string, data: any[],
    options: { transaction?: Transaction },
  ): Promise<any[]>;

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:131)
public async createForeignKey(model: string, column: string, type: string, references: {}) {
    return;
  }

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:122)
public async createIndex(model_name: string, index: IIndexProperty) {
    return;
  }

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:104)
public async createTable(model: string) {
    return;
  }

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:251)
public abstract async delete(model: string, conditions: any, options: { transaction?: Transaction }): Promise<number>;

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:141)
public async drop(model: string) {
    throw new Error('not implemented');
  }

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:230)
public abstract async find(model: string, conditions: any, options: IAdapterFindOptions): Promise<any>;

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:220)
public abstract async findById(
    model: string, id: any,
    options: { select?: string[], explain?: boolean, transaction?: Transaction },
  ): Promise<any>;

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:260)
public async getConnection(): Promise<any> {
    //
  }

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:94)
public async getSchemas(): Promise<ISchemas> {
    return { tables: {} };
  }

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:146)
public idToDB(value: any) {
    return value;
  }
(defined in /src/adapters/base.ts:76)
public key_type: any;
(defined in /src/adapters/base.ts:78)
public key_type_internal: any;
(defined in /src/adapters/base.ts:81)
public native_integrity = false;

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:265)
public async releaseConnection(adapter_connection: any): Promise<void> {
    //
  }

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:280)
public async rollbackTransaction(adapter_connection: any): Promise<void> {
    //
  }

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:162)
public setValuesFromDB(instance: any, data: any, schema: any, selected_columns: any) {
    if (!selected_columns) {
      selected_columns = Object.keys(schema);
    }
    const support_nested = this.support_nested;
    for (const column of selected_columns) {
      const property = schema[column];
      let value = support_nested ? util.getPropertyOfPath(data, property._parts_db) : data[property._dbname_us];
      if (value != null) {
        value = this.valueToModel(value, property);
      } else {
        value = null;
      }
      util.setPropertyOfPath(instance, property._parts, value);
    }
  }

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:270)
public async startTransaction(adapter_connection: any, isolation_level?: IsolationLevel): Promise<void> {
    //
  }

Parameters

(None)

Returns

(Nothing)

See Also:

(defined in /src/adapters/base.ts:237)
public abstract stream(model: any, conditions: any, options: IAdapterFindOptions): stream.Readable;
(defined in /src/adapters/base.ts:61)
public support_fractional_seconds = true;
(defined in /src/adapters/base.ts:70)
public support_geopoint = false;
(defined in /src/adapters/base.ts:67)
public support_nested = false;
(defined in /src/adapters/base.ts:73)
public support_string_type_with_length = false;
(defined in /src/adapters/base.ts:64)
public support_upsert = true;

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:198)
public abstract async update(model: string, data: any, options: { transaction?: Transaction }): Promise<void>;

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:204)
public abstract async updatePartial(
    model: string, data: any, conditions: any,
    options: { transaction?: Transaction },
  ): Promise<number>;

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:213)
public abstract async upsert(model: string, data: any, conditions: any, options: any): Promise<void>;

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:151)
public valueToDB(value: any, column: any, property: any) {
    if (property.type_class === types.Object || property.array) {
      return JSON.stringify(value);
    } else if (value != null) {
      return value;
    } else {
      return null;
    }
  }

Parameters

(None)

Returns

(Nothing)
(defined in /src/adapters/base.ts:290)
protected valueToModel(value: any, property: any) {
    if (property.type_class === types.Object || property.array) {
      return JSON.parse(value);
    } else {
      return value;
    }
  }

Parameters

NameTypeDescription
msg CORMO's error message
cause adapter specific error object

Returns

(Nothing)
(defined in /src/adapters/base.ts:48)
public static wrapError(msg: string, cause?: Error): Error {
    if (msg === 'unknown error' && cause && cause.message === 'transaction finished') {
      return cause;
    }
    const error = new Error(msg);
    (error as any).cause = cause;
    return error;
  }
Fork me on GitHub