Local Database Samebase In Flutter

Local Database Samebase In Flutter :

This flutter tutorial post is Local database sembase in flutter. It is support List data insert.

dependencies:
sembast:
path_provider:
flutter_bloc:
equatable:

Screenshot :

Local Database Samebase In Flutter

Project structure Screenshot :

Local Database Samebase In Flutter

Model package

-subject.dart

import 'package:meta/meta.dart';

class Subject {
  int id;

  final String name;
  final bool isLike;

  Subject({
    @required this.name,
    @required this.isLike,
  });

  Map<String, dynamic> toMap() {
    return {
      'name': name,
      'isLike': isLike,
    };
  }

  static Subject fromMap(Map<String, dynamic> map) {
    return Subject(
      name: map['name'],
      isLike: map['isLike'],
    );
  }
}

db Package

app_database.dart

import 'dart:async';

import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sembast/sembast.dart';
import 'package:sembast/sembast_io.dart';

class AppDatabase {
  // Singleton instance
  static final AppDatabase _singleton = AppDatabase._();

  // Singleton accessor
  static AppDatabase get instance => _singleton;

  // Completer is used for transforming synchronous code into asynchronous code.
  Completer<Database> _dbOpenCompleter;

  // A private constructor. Allows us to create instances of AppDatabase
  // only from within the AppDatabase class itself.
  AppDatabase._();

  // Sembast database object
  Database _database;

  // Database object accessor
  Future<Database> get database async {
    // If completer is null, AppDatabaseClass is newly instantiated, so database is not yet opened
    if (_dbOpenCompleter == null) {
      _dbOpenCompleter = Completer();
      // Calling _openDatabase will also complete the completer with database instance
      _openDatabase();
    }
    // If the database is already opened, awaiting the future will happen instantly.
    // Otherwise, awaiting the returned future will take some time - until complete() is called
    // on the Completer in _openDatabase() below.
    return _dbOpenCompleter.future;
  }

  Future _openDatabase() async {
    // Get a platform-specific directory where persistent app data can be stored
    final appDocumentDir = await getApplicationDocumentsDirectory();
    // Path with the form: /platform-specific-directory/demo.db
    final dbPath = join(appDocumentDir.path, 'demo.db');

    final database = await databaseFactoryIo.openDatabase(dbPath);
    // Any code awaiting the Completer's future will now start executing
    _dbOpenCompleter.complete(database);
  }
}

subject_dao.dart

import 'package:sembast/sembast.dart';
import 'app_database.dart';
import '../model/subject.dart';

class SubjectDao {
  static const String STORE_NAME = 'subject';
  // A Store with int keys and Map<String, dynamic> values.
  // This Store acts like a persistent map, values of which are subject objects converted to Map
  final _subjectStore = intMapStoreFactory.store(STORE_NAME);

  // Private getter to shorten the amount of code needed to get the
  // singleton instance of an opened database.
  Future<Database> get _db async => await AppDatabase.instance.database;

  Future insert(Subject subject) async {
    await _subjectStore.add(await _db, subject.toMap());
  }

  Future update(Subject subject) async {
    // For filtering by key (ID), RegEx, greater than, and many other criteria,
    // we use a Finder.
    final finder = Finder(filter: Filter.byKey(subject.id));
    await _subjectStore.update(
      await _db,
      subject.toMap(),
      finder: finder,
    );
  }

  Future delete(Subject subject) async {
    final finder = Finder(filter: Filter.byKey(subject.id));
    await _subjectStore.delete(
      await _db,
      finder: finder,
    );
  }

  Future<List<Subject>> getAllSortedByName() async {
    // Finder object can also sort data.
    final finder = Finder(sortOrders: [
      SortOrder('name'),
    ]);

    final recordSnapshots = await _subjectStore.find(
      await _db,
      finder: finder,
    );

    // Making a List<Subject> out of List<RecordSnapshot>
    return recordSnapshots.map((snapshot) {
      final subject = Subject.fromMap(snapshot.value);
      // An ID is a key of a record from the database.
      subject.id = snapshot.key;
      return subject;
    }).toList();
  }
}

Bloc Package

-subject_bloc.dart

import 'dart:async';
import 'dart:math';
import 'package:bloc/bloc.dart';
import '../model/subject.dart';
import '../db/subject_dao.dart';
import 'subject_event.dart';
import 'subject_state.dart';

class SubjectBloc extends Bloc<SubjectEvent, SubjectState> {
  SubjectDao _subjectDao = SubjectDao();

  // Display a loading indicator right from the start of the app
  @override
  SubjectState get initialState =>SubjectLoading();

  // This is where we place the logic.
  @override
  Stream<SubjectState> mapEventToState(
    SubjectEvent event,
  ) async* {
    if (event is Load) {
      // Indicating that subjects are being loaded - display progress indicator.
      yield SubjectLoading();
      yield* _reloadSubjects();
    } else if (event is AddRandomSubject) {
      await _subjectDao.insert(RandomGenerator.getRandomSubject());
      yield* _reloadSubjects();
    } else if (event is UpdateWithRandomSubject) {
      final newSubject = RandomGenerator.getRandomSubject();
      // Keeping the ID of the Subject the same
      newSubject.id = event.updatedSubject.id;
      await _subjectDao.update(newSubject);
      yield* _reloadSubjects();
    } else if (event is DeleteSubject) {
      await _subjectDao.delete(event.subject);
      yield* _reloadSubjects();
    }
  }

  Stream<SubjectState> _reloadSubjects() async* {
    final subjects = await _subjectDao.getAllSortedByName();
    // Yielding a state bundled with the Subjects from the database.
    yield SubjectLoaded(subjects);
  }
}

class RandomGenerator {
  static final _subjects = [
    Subject(name: 'Java', isLike: true),
    Subject(name: 'Android', isLike: true),
    Subject(name: 'Flutter', isLike: false),
    Subject(name: 'PHP', isLike: true),
    Subject(name: 'C', isLike: true),
    Subject(name: 'C++', isLike: false),
  ];

  static Subject getRandomSubject() {
    return _subjects[Random().nextInt(_subjects.length)];
  }
}

subject_event.dart

import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
import '../model/subject.dart';

@immutable
abstract class SubjectEvent extends Equatable {
  SubjectEvent([List props = const []]) : super(props);
}

class Load extends SubjectEvent {}

class AddRandomSubject extends SubjectEvent {}

class UpdateWithRandomSubject extends SubjectEvent {
  final Subject updatedSubject;

  UpdateWithRandomSubject(this.updatedSubject) : super([updatedSubject]);
}

class DeleteSubject extends SubjectEvent {
  final Subject subject;

  DeleteSubject(this.subject) : super([subject]);
}

subject_state.dart

import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';

import '../model/subject.dart';

@immutable
abstract class SubjectState extends Equatable {
  SubjectState([List props = const []]) : super(props);
}

class SubjectLoading extends SubjectState {}

class SubjectLoaded extends SubjectState {
  final List<Subject> subjects;

  SubjectLoaded(this.subjects) : super([subjects]);
}

home_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'bloc/subject_event.dart';
import 'model/subject.dart';
import 'bloc/subject_bloc.dart';
import 'bloc/subject_state.dart';

class HomePage extends StatefulWidget {
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  SubjectBloc _subjectBloc;

  @override
  void initState() {
    super.initState();
    _subjectBloc = BlocProvider.of<SubjectBloc>(context);
    _subjectBloc.dispatch(Load());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SEMBAST DATABASE'),
      ),
      body: _buildBody(),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          _subjectBloc.dispatch(AddRandomSubject());
        },
      ),
    );
  }

  Widget _buildBody() {
    return BlocBuilder(
      bloc: _subjectBloc,
      // Whenever there is a new state emitted from the bloc, builder runs.
      builder: (BuildContext context, SubjectState state) {
        if (state is SubjectLoading) {
          return Center(
            child: CircularProgressIndicator(),
          );
        } else if (state is SubjectLoaded) {
          return ListView.builder(
            itemCount: state.subjects.length,
            itemBuilder: (context, index) {
              final displayed = state.subjects[index];
              return ListTile(
                title: Text(displayed.name),
                subtitle:
                    Text(displayed.isLike ? 'Like!' : 'Sooo sour!'),
                trailing: _buildUpdateDeleteButtons(displayed),
              );
            },
          );
        }
        return Container();
      },
    );
  }

  Row _buildUpdateDeleteButtons(Subject subject) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        IconButton(
          icon: Icon(Icons.refresh),
          onPressed: () {
            _subjectBloc.dispatch(UpdateWithRandomSubject(subject));
          },
        ),
        IconButton(
          icon: Icon(Icons.delete_outline),
          onPressed: () {
            _subjectBloc.dispatch(DeleteSubject(subject));
          },
        ),
      ],
    );
  }
}

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'bloc/subject_bloc.dart';
import 'home_page.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      builder: (context) => SubjectBloc(),
      child: MaterialApp(
        title: 'Flutter Tutorial',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          accentColor: Colors.blue,
        ),
        home: HomePage(),
      ),
    );
  }
}

The flutter tutorial  is a website that bring you the latest and amazing resources of code. All the languages codes are included in this website. The languages like flutter, android, java,kotlin etc.with the help of this languages any user can develop the beautiful application

For more information about Flutter. visit www.fluttertutorial.in