flutter_sqlite_m8_generator 0.2.3+1

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • new51

Sqlite ORM Mate Generator (flutter-sqlite-m8-generator) #

GitHub release pub package Build Status

Introduction #

Dart package to generate SQLite ready-to-go fixture. Uses Dart Build System builders. Based on flutter-orm-m8 annotations convention this package generates proxies and database adapter for SQLite.

Dependencies #

It depends on dart package flutter-orm-m8. Read README.md for implemented annotation convention.

Usage #

  1. Create a flutter project

  2. Add flutter_orm_m8, sqflite, build_runner, flutter_sqlite_m8_generator dependencies to pubspec.yaml

    • Before

        dependencies:
            flutter:
                sdk: flutter
      
            cupertino_icons: ^0.1.2
      
        dev_dependencies:
            flutter_test:
                sdk: flutter
      
    • After

        dependencies:
            flutter_orm_m8: ^0.4.0
            sqflite: ^1.1.0
            flutter:
                sdk: flutter
      
            cupertino_icons: ^0.1.2
      
        dev_dependencies:
            build_runner: ^1.0.0
            flutter_sqlite_m8_generator: ^0.2.3+1
            flutter_test:
                sdk: flutter
      
      
  3. Add build.yaml file with the following content

     targets:
         $default:
             builders:
                 flutter_sqlite_m8_generator|orm_m8:
                     generate_for:
                         - lib/models/*.dart
                         - lib/main.dart
    
  4. Refresh packages

    flutter packages get
    
  5. In the lib folder create a new one named models

  6. In the models folder add model classes for your business objects.

  7. Using flutter-orm-m8 annotations convention mark:

    • classes with @DataTable
    • fields with @DataColumn
  8. Run the build_runner

    flutter packages pub run build_runner build --delete-conflicting-outputs
    

    The build_runner will generate:

    • in models folder, a *.g.m8.dart file for each model file
    • in lib folder, a main.adapter.g.m8.dart file
  9. Use the generated proxies and adapter in order to easily develop CRUD behavior. See the example for a trivial usage.

Example #

A full, flutter working example is maintained on https://github.com/matei-tm/flutter-sqlite-m8-generator/tree/master/example

usecase001

A DbEntity implementation #

We added a HealthEntry model that implements DbEntity. Adding a model file independent/health_entry.dart with the following content:

import 'package:flutter_orm_m8/flutter_orm_m8.dart';

@DataTable(
    "health_entries", TableMetadata.TrackCreate | TableMetadata.TrackUpdate)
class HealthEntry implements DbEntity {
  @DataColumn(
      "id",
      ColumnMetadata.PrimaryKey |
          ColumnMetadata.Unique |
          ColumnMetadata.AutoIncrement)
  int id;

  @DataColumn("description", ColumnMetadata.Unique)
  String description;

  @DataColumn("diagnosys_date")
  DateTime diagnosysDate;

  @DataColumn("my_future_column", ColumnMetadata.Ignore | ColumnMetadata.Unique)
  int futureData;
}

the builder creates independent/health_entry.g.m8.dart file with content

// GENERATED CODE - DO NOT MODIFY BY HAND

// **************************************************************************
// Generator: OrmM8GeneratorForAnnotation
// **************************************************************************

import 'package:sqflite/sqflite.dart';
import 'dart:async';
import 'package:example/models/independent/health_entry.dart';

class HealthEntryProxy extends HealthEntry {
  DateTime dateCreate;
  DateTime dateUpdate;

  HealthEntryProxy();

  Map<String, dynamic> toMap() {
    var map = Map<String, dynamic>();
    map['id'] = id;
    map['description'] = description;
    map['diagnosys_date'] = diagnosysDate.millisecondsSinceEpoch;
    map['date_create'] = dateCreate.millisecondsSinceEpoch;
    map['date_update'] = dateUpdate.millisecondsSinceEpoch;

    return map;
  }

  HealthEntryProxy.fromMap(Map<String, dynamic> map) {
    this.id = map['id'];
    this.description = map['description'];
    this.diagnosysDate =
        DateTime.fromMillisecondsSinceEpoch(map['diagnosys_date']);
    this.dateCreate = DateTime.fromMillisecondsSinceEpoch(map['date_create']);
    this.dateUpdate = DateTime.fromMillisecondsSinceEpoch(map['date_update']);
  }
}

mixin HealthEntryDatabaseHelper {
  Future<Database> db;
  final theHealthEntryColumns = [
    "id",
    "description",
    "diagnosys_date",
    "date_create",
    "date_update"
  ];

  final String _theHealthEntryTableHandler = 'health_entries';

  Future createHealthEntryTable(Database db) async {
    await db.execute(
        'CREATE TABLE $_theHealthEntryTableHandler (id INTEGER  PRIMARY KEY AUTOINCREMENT UNIQUE, description TEXT  UNIQUE, diagnosys_date INTEGER , date_create INTEGER, date_update INTEGER)');
  }

  Future<int> saveHealthEntry(HealthEntryProxy instanceHealthEntry) async {
    var dbClient = await db;

    instanceHealthEntry.dateCreate = DateTime.now();
    instanceHealthEntry.dateUpdate = DateTime.now();

    var result = await dbClient.insert(
        _theHealthEntryTableHandler, instanceHealthEntry.toMap());
    return result;
  }

  Future<List> getHealthEntrysAll() async {
    var dbClient = await db;
    var result = await dbClient.query(_theHealthEntryTableHandler,
        columns: theHealthEntryColumns, where: '1');

    return result.toList();
  }

  Future<int> getHealthEntrysCount() async {
    var dbClient = await db;
    return Sqflite.firstIntValue(await dbClient.rawQuery(
        'SELECT COUNT(*) FROM $_theHealthEntryTableHandler  WHERE 1'));
  }

  Future<HealthEntry> getHealthEntry(int id) async {
    var dbClient = await db;
    List<Map> result = await dbClient.query(_theHealthEntryTableHandler,
        columns: theHealthEntryColumns, where: '1 AND id = ?', whereArgs: [id]);

    if (result.length > 0) {
      return HealthEntryProxy.fromMap(result.first);
    }

    return null;
  }

  Future<int> deleteHealthEntry(int id) async {
    var dbClient = await db;
    return await dbClient
        .delete(_theHealthEntryTableHandler, where: 'id = ?', whereArgs: [id]);
  }

  Future<bool> deleteHealthEntrysAll() async {
    var dbClient = await db;
    await dbClient.delete(_theHealthEntryTableHandler);
    return true;
  }

  Future<int> updateHealthEntry(HealthEntryProxy instanceHealthEntry) async {
    var dbClient = await db;

    instanceHealthEntry.dateUpdate = DateTime.now();

    return await dbClient.update(
        _theHealthEntryTableHandler, instanceHealthEntry.toMap(),
        where: "id = ?", whereArgs: [instanceHealthEntry.id]);
  }
}

and database adapter file main.adapter.g.m8.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

// **************************************************************************
// DatabaseHelperGenerator
// **************************************************************************

import 'dart:async';

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

import 'package:example/models/independent/health_entry.g.m8.dart';

class DatabaseHelper with HealthEntryDatabaseHelper {
  static final DatabaseHelper _instance = DatabaseHelper.internal();
  static Database _db;

  /// if [extremeDevelopmentMode] is true then the database will be deleteted on each init
  bool extremeDevelopmentMode = false;

  factory DatabaseHelper() => _instance;
  DatabaseHelper.internal();

  Future<Database> get db async {
    if (_db != null) {
      return _db;
    }
    _db = await initDb();

    return _db;
  }

  initDb() async {
    String databasesPath = await getDatabasesPath();
    String path = join(databasesPath, 'm8_store_0.2.0.db');

    if (extremeDevelopmentMode) {
      await deleteDatabase(path);
    }

    var db = await openDatabase(path, version: 2, onCreate: _onCreate);
    return db;
  }

  void _onCreate(Database db, int newVersion) async {
    await createHealthEntryTable(db);
  }

  Future close() async {
    var dbClient = await db;
    return dbClient.close();
  }

  Future deleteAll() async {
    await deleteHealthEntrysAll();
  }
}

Changelog #

[Unreleased]

[0.2.3+1] - 2019-04-15

Fixed #

  • Fix typo in save and update methods for trackable entities

Changed #

  • The showcase in the example project. All models are closer to a real life application

[0.2.3] - 2019-04-14

Fixed #

  • The generated entity database helper does not contain the meta columns
  • Fixed test in the example project

Changed #

  • The showcase in the example project

[0.2.2] - 2019-04-12

Added #

  • Bidirectional mapping for Model DateTime to Database Integer
  • Complete implementation for trackable, update and create, fields
  • Boolean extremeDevelopmentMode field to DatabaseHelper to control regeneration of database in dev mode

[0.2.1] - 2019-04-09

Changed #

  • Emitting only public fields

Fixed #

  • Missing metadataLevel on DataColumn annotated model fields, generates wrong emition

[0.2.0] - 2019-04-07

Added #

  • A full implementation in the example project for a dbEntity CRUD

Fixed #

  • Returning all rows on softDeletable entities

[0.1.1] - 2019-04-06

Changed #

  • FileStamp for database file

Fixed #

  • Fixing format and analyzer issues recommended after publish
  • Fixing readme formatting issues

[0.1.0] - 2019-04-05

Added #

  • Chaining database adapter builder with annotation helpers builder
  • Tests
  • A proxy default constructor with mandatory parameters
  • A database adapter

Changed #

  • Generated files extension

[0.0.7] - 2019-04-03

Added #

  • Working generator, ready to be published
  • Soft delete annotation implemented
  • Track create annotation implemented
  • Track update annotation implemented

[0.0.6] - 2019-04-02

Added #

  • Proxy writer

[0.0.5] - 2019-04-01

Added #

  • A simple fields enumeration with model type
  • A basic type mapper for Sqlite types
  • Expanding metadata in column definition
  • Extracting the primary key name

[0.0.4] - 2019-03-22

Added #

  • An entity factory for account related, account and independent entities

Changed #

  • The build output is routed to cache

[0.0.3] - 2019-03-14

Added #

  • A weak try to expand some information
  • Tests

[0.0.2] - 2019-03-14

Fixed #

  • Fixing analyzer issues

[0.0.1] - 2019-03-03

Added #

  • Basic generator

example/example.dart

import 'package:flutter_orm_m8/flutter_orm_m8.dart';

@DataTable("my_health_entries_table")
class HealthEntry implements DbEntity {
  @DataColumn(
      "my_id_column",
      ColumnMetadata.PrimaryKey |
          ColumnMetadata.Unique |
          ColumnMetadata.AutoIncrement)
  int id;

  @DataColumn("my_description_column", ColumnMetadata.Unique)
  String description;

  @DataColumn("my_future_column", ColumnMetadata.Ignore | ColumnMetadata.Unique)
  int futureData;
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  flutter_sqlite_m8_generator: ^0.2.3+1

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:flutter_sqlite_m8_generator/builder.dart';
import 'package:flutter_sqlite_m8_generator/exceptions/exception_expander.dart';
import 'package:flutter_sqlite_m8_generator/exceptions/field_parse_exception.dart';
import 'package:flutter_sqlite_m8_generator/generator/core.dart';
import 'package:flutter_sqlite_m8_generator/generator/database_helper_generator.dart';
import 'package:flutter_sqlite_m8_generator/generator/emitted_entity.dart';
import 'package:flutter_sqlite_m8_generator/generator/entity_writer.dart';
import 'package:flutter_sqlite_m8_generator/generator/model_parser.dart';
import 'package:flutter_sqlite_m8_generator/generator/orm_m8_generator_for_annotation.dart';
import 'package:flutter_sqlite_m8_generator/generator/utils/attribute_metadata_parser.dart';
import 'package:flutter_sqlite_m8_generator/generator/utils/db_entity_type_enum.dart';
import 'package:flutter_sqlite_m8_generator/generator/utils/entity_attribute.dart';
import 'package:flutter_sqlite_m8_generator/generator/utils/type/checkers.dart';
import 'package:flutter_sqlite_m8_generator/generator/utils/type/column_assertions.dart';
import 'package:flutter_sqlite_m8_generator/generator/utils/type/table_assertions.dart';
import 'package:flutter_sqlite_m8_generator/generator/utils/type_mapper.dart';
import 'package:flutter_sqlite_m8_generator/generator/utils/type_utils.dart';
import 'package:flutter_sqlite_m8_generator/generator/utils/utils.dart';
import 'package:flutter_sqlite_m8_generator/generator/writers/account_entity_writer.dart';
import 'package:flutter_sqlite_m8_generator/generator/writers/account_related_entity_writer.dart';
import 'package:flutter_sqlite_m8_generator/generator/writers/attribute_writer.dart';
import 'package:flutter_sqlite_m8_generator/generator/writers/database_helper_writer.dart';
import 'package:flutter_sqlite_m8_generator/generator/writers/entity_writer_factory.dart';
import 'package:flutter_sqlite_m8_generator/generator/writers/independent_entity_writer.dart';
import 'package:flutter_sqlite_m8_generator/generator/writers/proxy_writer.dart';
import 'package:flutter_sqlite_m8_generator/m8_builder.dart';
import 'package:flutter_sqlite_m8_generator/orm_m8_generator.dart';
  
Version Uploaded Documentation Archive
0.2.3+1 Apr 14, 2019 Go to the documentation of flutter_sqlite_m8_generator 0.2.3+1 Download flutter_sqlite_m8_generator 0.2.3+1 archive
0.2.3 Apr 14, 2019 Go to the documentation of flutter_sqlite_m8_generator 0.2.3 Download flutter_sqlite_m8_generator 0.2.3 archive
0.2.2 Apr 12, 2019 Go to the documentation of flutter_sqlite_m8_generator 0.2.2 Download flutter_sqlite_m8_generator 0.2.2 archive
0.2.1 Apr 8, 2019 Go to the documentation of flutter_sqlite_m8_generator 0.2.1 Download flutter_sqlite_m8_generator 0.2.1 archive
0.2.0 Apr 7, 2019 Go to the documentation of flutter_sqlite_m8_generator 0.2.0 Download flutter_sqlite_m8_generator 0.2.0 archive
0.1.1 Apr 5, 2019 Go to the documentation of flutter_sqlite_m8_generator 0.1.1 Download flutter_sqlite_m8_generator 0.1.1 archive
0.1.0 Apr 5, 2019 Go to the documentation of flutter_sqlite_m8_generator 0.1.0 Download flutter_sqlite_m8_generator 0.1.0 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
2
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
51
Learn more about scoring.

We analyzed this package on Apr 16, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.2.0
  • pana: 0.12.14

Platforms

Detected platforms: other

Platform components identified in package: build, io, mirrors.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
analyzer ^0.35.0 0.35.4 0.36.0
build >=0.12.0 <2.0.0 1.1.3
flutter_orm_m8 ^0.4.0 0.4.0 0.6.0
path ^1.6.2 1.6.2
source_gen ^0.9.0 0.9.4+2
Transitive dependencies
args 1.5.1
async 2.2.0
charcode 1.1.2
collection 1.14.11
convert 2.1.1
crypto 2.0.6
dart_style 1.2.4 1.2.7
front_end 0.1.14 0.1.15
glob 1.1.7
kernel 0.3.14 0.3.15
logging 0.11.3+2
meta 1.1.7
package_config 1.0.5
pedantic 1.5.0
pub_semver 1.4.2
source_span 1.5.5
string_scanner 1.0.4
term_glyph 1.1.0
typed_data 1.1.6
watcher 0.9.7+10
yaml 2.1.15
Dev dependencies
build_runner ^1.0.0
build_test ^0.10.0
build_verify ^1.1.0
source_gen_test ^0.1.0
test ^1.3.3