Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support embedded objects #829

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:

- name: Install dependencies
run: flutter packages get
working-directory: floor
working-directory: floor_common

- name: Run generator
run: flutter packages pub run build_runner build --delete-conflicting-outputs
Expand Down
3 changes: 2 additions & 1 deletion example/lib/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import 'dart:async';

import 'package:example/task.dart';
import 'package:example/task_dao.dart';
import 'package:example/timestamp.dart';
import 'package:example/type_converter.dart';
import 'package:floor/floor.dart';
import 'package:sqflite/sqflite.dart' as sqflite;

part 'database.g.dart';

@Database(version: 1, entities: [Task])
@TypeConverters([DateTimeConverter, TaskTypeConverter])
@Database(version: 1, entities: [Task], embeds: [Timestamp])
abstract class FlutterDatabase extends FloorDatabase {
TaskDao get taskDao;
}
41 changes: 33 additions & 8 deletions example/lib/database.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:example/database.dart';
import 'package:example/task.dart';
import 'package:example/task_dao.dart';
import 'package:example/timestamp.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
Expand Down Expand Up @@ -179,7 +180,7 @@ class TaskListCell extends StatelessWidget {
child: ListTile(
title: Text(task.message),
subtitle: Text('Status: ${task.statusTitle}'),
trailing: Text(task.timestamp.toIso8601String()),
trailing: Text(task.timestamp.format()),
),
confirmDismiss: (direction) async {
String? statusMessage;
Expand Down Expand Up @@ -263,7 +264,13 @@ class TasksTextField extends StatelessWidget {
if (message.trim().isEmpty) {
_textEditingController.clear();
} else {
final task = Task.optional(message: message, type: TaskType.task);
final task = Task.optional(
message: message,
type: TaskType.task,
timestamp: Timestamp(
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
));
await dao.insertTask(task);
_textEditingController.clear();
}
Expand Down
13 changes: 9 additions & 4 deletions example/lib/task.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:example/timestamp.dart';
import 'package:floor/floor.dart';

enum TaskStatus {
Expand Down Expand Up @@ -29,7 +30,7 @@ class Task {

final bool? isRead;

final DateTime timestamp;
final Timestamp timestamp;

final TaskStatus? status;

Expand All @@ -46,7 +47,7 @@ class Task {

factory Task.optional({
int? id,
DateTime? timestamp,
Timestamp? timestamp,
String? message,
bool? isRead,
TaskStatus? status,
Expand All @@ -56,7 +57,11 @@ class Task {
id,
isRead ?? false,
message ?? 'empty',
timestamp ?? DateTime.now(),
timestamp ??
Timestamp(
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
),
status,
type,
);
Expand All @@ -70,7 +75,7 @@ class Task {
int? id,
String? message,
bool? isRead,
DateTime? timestamp,
Timestamp? timestamp,
TaskStatus? status,
TaskType? type,
}) {
Expand Down
37 changes: 37 additions & 0 deletions example/lib/timestamp.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'package:floor/floor.dart';
import 'package:intl/intl.dart';

@Embed()
hendrikvdkaaden marked this conversation as resolved.
Show resolved Hide resolved
@Entity()
class Timestamp {
@ColumnInfo(name: 'created_at')
final DateTime createdAt;

@ColumnInfo(name: 'updated_at')
final DateTime updatedAt;

Timestamp({required this.createdAt, required this.updatedAt});

@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Timestamp &&
runtimeType == other.runtimeType &&
createdAt == other.createdAt &&
updatedAt == other.updatedAt;

@override
int get hashCode => createdAt.hashCode ^ updatedAt.hashCode;

String format() {
final DateFormat formatter = DateFormat('yyyy-MM-dd');
final String formattedCreatedAt = formatter.format(createdAt);
final String formattedUpdatedAt = formatter.format(updatedAt);
return 'Created at: $formattedCreatedAt \nUpdated at: $formattedUpdatedAt';
}

@override
String toString() {
return 'Timestamp(createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
10 changes: 9 additions & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ packages:
path: "../floor"
relative: true
source: path
version: "1.4.2"
version: "1.5.0"
floor_annotation:
dependency: transitive
description:
Expand Down Expand Up @@ -311,6 +311,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
intl:
dependency: "direct main"
description:
name: intl
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
url: "https://pub.dev"
source: hosted
version: "0.17.0"
io:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies:
flutter:
sdk: flutter
sqflite: any # This dependency is needed to solve the problem with warning about transitive dependencies
intl: ^0.17.0

dev_dependencies:
analyzer: ^6.4.1
Expand Down
2 changes: 2 additions & 0 deletions example/test/main_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ void main() {
});

tearDown(() async {
//Delay is necessary, otherwise test wil fail after completion
await Future.delayed(const Duration(milliseconds: 100));
hendrikvdkaaden marked this conversation as resolved.
Show resolved Hide resolved
await database.close();
});

Expand Down
1 change: 1 addition & 0 deletions floor_annotation/lib/floor_annotation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export 'src/dao.dart';
export 'src/database.dart';
export 'src/database_view.dart';
export 'src/delete.dart';
export 'src/embed.dart';
export 'src/entity.dart';
export 'src/foreign_key.dart';
export 'src/fts.dart';
Expand Down
4 changes: 4 additions & 0 deletions floor_annotation/lib/src/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ class Database {
/// The entities the database manages.
final List<Type> entities;

/// The embeds the database manages.
final List<Type> embeds;

/// The views the database manages.
final List<Type> views;

/// Marks a class as a FloorDatabase.
const Database({
required this.version,
required this.entities,
this.embeds = const [],
this.views = const [],
});
}
5 changes: 5 additions & 0 deletions floor_annotation/lib/src/embed.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Embed {
const Embed();
}

const embed = Embed();
1 change: 1 addition & 0 deletions floor_generator/lib/misc/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ abstract class AnnotationField {
static const onConflict = 'onConflict';

static const databaseVersion = 'version';
static const databaseEmbeds = 'embeds';
static const databaseEntities = 'entities';
static const databaseViews = 'views';

Expand Down
13 changes: 13 additions & 0 deletions floor_generator/lib/misc/extension/embeds_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:collection/collection.dart';
import 'package:floor_generator/value_object/embed.dart';
import 'package:floor_generator/value_object/type_converter.dart';

extension EmbedsExtension on Iterable<Embed> {
/// Returns the [Embed] in the closest [TypeConverterScope] for
/// [dartType] or null
Embed? getClosestOrNull(DartType dartType) {
return toList().firstWhereOrNull(
(embed) => embed.classElement.name == dartType.toString());
}
}
15 changes: 15 additions & 0 deletions floor_generator/lib/misc/extension/field_element_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:floor_annotation/floor_annotation.dart' as annotations;
import 'package:floor_generator/misc/type_utils.dart';

extension FieldElementExtension on FieldElement {
bool shouldBeIncluded() {
final isIgnored = hasAnnotation(annotations.ignore.runtimeType);
return !(isStatic || isSynthetic || isIgnored);
}

bool get isEmbedded {
return (type.element?.hasAnnotation(annotations.Embed) ?? false) &&
type.element is ClassElement;
}
}
Loading
Loading