Flutter SQLite FFI с использованием болота

Цель этого поста — продемонстрировать «Как использовать SQLite FFI с библиотекой moor?».

Flutter Mobile может использовать дартс:библиотека ffi для вызова собственных API-интерфейсов C. FFI означает внешний функциональный интерфейс. Другие термины для аналогичной функциональности включают собственный интерфейс и языковые привязки.

Проще говоря, нам не нужен какой-либо канал метода для вызова собственного API Android/IOS. Мы можем напрямую получить доступ к тем, кто находится в дротике, с помощью ffi.

Давайте начнем:
Мавр
Мур ффи

Шаг: 1 Добавьте зависимости в pubspec
Добавьте следующие зависимости в свой pubspec.yaml.

moor: ^2.0.0
moor_ffi: ^0.0.1

provider: ^3.0.0+1
path_provider: ^1.3.0

dev_dependencies:
  moor_generator: ^2.0.0
  build_runner: 

Шаг: 2 создайте простой класс сущности (movie_entity.dart)

import 'package:moor/moor.dart';

class MovieEntity extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get name => text().withLength(min: 1, max: 50)();
}

Шаг: 3 создайте класс базы данных (app_db.dart)

import 'dart:io';

import 'package:moor/moor.dart';
import 'package:moor_ffi/moor_ffi.dart';

import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;

import 'movie_entity.dart';

part 'app_db.g.dart';

@UseMoor(tables: [MovieEntity])
class AppDatabase extends _$AppDatabase {
  AppDatabase()
      : super(
          LazyDatabase(() async {
            final dbFolder = await getApplicationDocumentsDirectory();
            final file = File(p.join(dbFolder.path, 'myDB.sqlite'));
            return VmDatabase(file);
          }),
        );

  @override
  int get schemaVersion => 1;
  
  // This two methods can be extracted in DAO. 
  Future insertMovie(MovieEntityData movie) => into(movieEntity).insert(movie);
  Stream<List<MovieEntityData>> watchAllMovies() => select(movieEntity).watch();
}

Давайте запустим BuildRunner для генерации кода.
flutter pub run build_runner build
Как только мы сгенерируем код, мы увидим MovieEntityData как DataClass и movieEntity как Table.

Шаг: 4 Давайте создадим пользовательский интерфейс (home_page.dart)

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:sql_ffi/app_db.dart';

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

class _HomePageState extends State<HomePage> {
  final TextEditingController _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    final AppDatabase appDatabase = Provider.of<AppDatabase>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('SQL FFI Demo'),
      ),
      body: Column(
        children: <Widget>[
          StreamBuilder(
            stream: appDatabase.watchAllMovies(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              if (snapshot.hasData) {
                List<MovieEntityData> users = snapshot.data;
                if (users.isNotEmpty) {
                  return Expanded(
                    flex: 5,
                    child: ListView.separated(
                      padding: const EdgeInsets.all(16),
                      itemCount: users.length,
                      itemBuilder: (BuildContext context, int index) {
                        return ListTile(
                          title: Text(users[index].name),
                        );
                      },
                      separatorBuilder: (BuildContext context, int index) =>
                          const Divider(),
                    ),
                  );
                }
              }
              return const SizedBox(height: 10);
            },
          ),
          const SizedBox(height: 20),
          Container(
            padding: const EdgeInsets.all(10.0),
            color: Colors.grey[200],
            child: Align(
              alignment: Alignment.bottomCenter,
              child: Column(
                children: <Widget>[
                  TextField(
                    decoration: InputDecoration(
                      hintText: 'Enter movie name',
                    ),
                    controller: _controller,
                  ),
                  RaisedButton(
                    child: const Text('Save Movie'),
                    onPressed: () async {
                      final movieName = _controller.text;
                      if (movieName.isNotEmpty) {
                        int id = Random().nextInt(100);
                        MovieEntityData movieEntity =
                            MovieEntityData(id: id, name: '$movieName');
                        await appDatabase.insertMovie(movieEntity);
                        _controller.clear();
                      }
                    },
                  ),
                ],
              ),
            ),
          ),
          const SizedBox(height: 20),
        ],
      ),
    );
  }
}

Шаг:5 Давайте создадим пользовательский интерфейс (main.dart)

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'app_db.dart';
import 'home_page.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider(
      builder: (_) => AppDatabase(),
      child: MaterialApp(
        title: 'Material App',
        home: HomePage(),
      ),
    );
  }
}

Вот и наслаждайся 😃

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *