getObjects function

Future<List<SqfEntityTableBase>> getObjects(
  1. List objectList,
  2. SqfEntityProvider bundledDbModel,
  3. SqfEntityModelProvider model
)

Method for Creating DB Model from DB

Implementation

Future<List<SqfEntityTableBase>> getObjects(List objectList,
    SqfEntityProvider bundledDbModel, SqfEntityModelProvider model) async {
  final tables = <SqfEntityTableBase>[];
  for (final table in objectList) {
    if ([
      'android_metadata',
      'sqfentitytables',
      'sqfentitysequences',
      'sqlite_sequence'
    ].contains(table['name'].toString())) {
      continue;
    }
    final tableName = table['name'].toString();
    final objectType =
        table['type'].toString() == 'view' ? ObjectType.view : ObjectType.table;
    String? primaryKeyName;
    final List<String>? primaryKeyNames = <String>[];
    bool? isIdentity = false;
    bool? isPrimaryKeyText = false;
    String? sqlStatement;
    // check fields in the table
    final tableFields =
        await bundledDbModel.execDataTable('PRAGMA table_info(`$tableName`)');
    final existingDBfields = <SqfEntityFieldType>[];
    if (tableFields.isNotEmpty) {
      // check primary key in the table
      for (final row in tableFields) {
        if (row['pk'].toString() != '0') {
          primaryKeyName = row['name'].toString();
          isPrimaryKeyText = row['type'].toString().toLowerCase() == 'text';
          primaryKeyNames!.add(primaryKeyName);
          final isAutoIncrement = await bundledDbModel.execScalar(
              'SELECT "is-autoincrement" FROM sqlite_master WHERE tbl_name LIKE \'$tableName\' AND sql LIKE "%AUTOINCREMENT%"');
          isIdentity = isAutoIncrement != null;
          //break;
        }
      }
      if (objectType == ObjectType.table) {
        primaryKeyName = primaryKeyName ?? tableFields[0]['name'].toString();
      } else {
        sqlStatement = (await bundledDbModel.execScalar(
                'SELECT sql FROM sqlite_master WHERE tbl_name LIKE \'$tableName\''))
            .toString();
        sqlStatement = sqlStatement.substring(sqlStatement.indexOf('SELECT'));
      }

      /// convert table fields to SqfEntityField
      for (int i = 0; i < tableFields.length; i++) {
        if (tableFields[i]['name'].toString() != primaryKeyName) {
          existingDBfields.add(SqfEntityFieldBase(
              tableFields[i]['name'].toString(),
              parseDbType(tableFields[i]['type'].toString()),
              isPrimaryKeyField:
                  primaryKeyNames!.contains(tableFields[i]['name'])));
        }
      }
    }
    tables.add(SqfEntityTableBase()
      ..tableName = tableName
      ..objectType = objectType
      ..sqlStatement = sqlStatement
      ..modelName = toCamelCase(tableName)
      ..primaryKeyName = primaryKeyName
      ..primaryKeyType = isPrimaryKeyText!
          ? PrimaryKeyType.text
          : isIdentity!
              ? PrimaryKeyType.integer_auto_incremental
              : PrimaryKeyType.integer_unique
      ..fields = existingDBfields);
    if (objectType == ObjectType.table) {
      tables.last
        ..primaryKeyNames.add(primaryKeyName!)
        ..primaryKeyTypes.add('int');
    }
  }

  /// set RelationShips
  for (var table in tables) {
    final relationFields = <SqfEntityFieldRelationshipBase>[];
    final foreignKeys = await bundledDbModel.getForeignKeys(table.tableName!);
    if (foreignKeys.isNotEmpty) {
      print(
          'SQFENTITY.convertDatabaseToModelBase---------------${foreignKeys.length} foreign keys found in ${model.bundledDatabasePath}/${table.tableName}:');
      printList(foreignKeys);
      for (final fKey in foreignKeys) {
        for (final parentTable in tables) {
          if (parentTable.tableName!.toLowerCase() ==
              fKey['table'].toString().toLowerCase()) {
            /// bir foreign key, primary key olarak ayarlanmışsa relationship alanına dönüştür
            /// Set field as Relatianship if it set as primarykey and foreign key
            if (table.primaryKeyName!.toLowerCase() ==
                fKey['from'].toString().toLowerCase()) {
              relationFields.add(SqfEntityFieldRelationshipBase(
                  parentTable, getDeleteRule(fKey['on_delete'].toString()))
                ..fieldName = table.primaryKeyName!
                ..isPrimaryKeyField = true
                ..dbType = table.primaryKeyType == PrimaryKeyType.text
                    ? DbType.text
                    : DbType.integer);
              table
                ..primaryKeyName = ''
                ..primaryKeyType = null;
            }
            for (final field in table.fields!) {
              if (field.fieldName!.toLowerCase() ==
                  fKey['from'].toString().toLowerCase()) {
                relationFields.add(SqfEntityFieldRelationshipBase(
                    parentTable, getDeleteRule(fKey['on_delete'].toString()))
                  ..fieldName = field.fieldName
                  ..dbType = field.dbType);
              }
            }
          }
        }
        //print(fKey.toString());
      }
    } else {
      // if foreignKeys is Empty
      for (final field in table.fields!) {
        if (field.fieldName!.toLowerCase() != 'id' &&
            (field.dbType == DbType.integer ||
                field.dbType == DbType.numeric)) {
          for (final parentTable
              in tables.where((t) => t.objectType == ObjectType.table)) {
            if (parentTable.tableName != table.tableName &&
                ((parentTable.primaryKeyName!.toLowerCase() ==
                        field.fieldName!.toLowerCase()) ||
                    ('${parentTable.tableName}${parentTable.primaryKeyName}'
                            .toLowerCase() ==
                        field.fieldName!.toLowerCase()))) {
              print(
                  'relationship column (${field.fieldName}) found on the table ${parentTable.tableName}');
              relationFields.add(SqfEntityFieldRelationshipBase(
                  parentTable, DeleteRule.NO_ACTION)
                ..fieldName = field.fieldName
                ..dbType = field.dbType);
            }
          }
        }
      }
    }
    if (relationFields.isNotEmpty) {
      for (final relationField in relationFields) {
        try {
          final field = table.fields!
              .singleWhere((f) => f.fieldName == relationField.fieldName);
          relationField.isPrimaryKeyField = field.isPrimaryKeyField;
          table.fields!.remove(field);
        } catch (e) {
          print(e.toString());
        }
        table.fields!.add(relationField);
      }
    }
  }

  /// SET MANY TO MANY RELATIONS
  final manyToManyTables = <SqfEntityTableBase>[];
  for (var table in tables) {
    if (table.fields!.length == 2 &&
        table.fields!.whereType<SqfEntityFieldRelationshipBase>().length == 2) {
      final ref = table.fields![0] as SqfEntityFieldRelationshipBase;
      final referred = table.fields![1] as SqfEntityFieldRelationshipBase;
      ref.table!.fields!
          .add(SqfEntityFieldRelationshipBase(referred.table, ref.deleteRule)
            ..fieldName = 'm${table.tableName}'
            ..manyToManyTableName = table.tableName!
            ..relationType = RelationType.MANY_TO_MANY);
      table.relationType = RelationType.MANY_TO_MANY;
      //tables.remove(table);
      manyToManyTables.add(table);
    }
  }
  return tables;
}