Skip to content

Instantly share code, notes, and snippets.

@Abolfazl-MI
Created February 25, 2023 13:00
Show Gist options
  • Save Abolfazl-MI/b0500fe969d250c1b952cbb56683fdd9 to your computer and use it in GitHub Desktop.
Save Abolfazl-MI/b0500fe969d250c1b952cbb56683fdd9 to your computer and use it in GitHub Desktop.
sample for dependenci inversion
import 'package:taskino/core/data_response.dart';
import 'package:taskino/models/category_model.dart';
import 'package:taskino/models/project_model.dart';
import 'package:taskino/models/task_model.dart';
abstract class DataBaseAdaptor{
// Create opreations
Future<DataResponse> createProject(ProjectModel project);
Future<DataResponse>createTask(TaskModel task,);
Future<DataResponse>createCategory(CategoryModel category);
// Read opreations
Future<DataResponse>getAllProjects();
Future<DataResponse>getProjectDetail(int projectId);
Future<DataResponse>getTaskDetail(int taskId);
Future<DataResponse>getAllCategories();
Future<DataResponse>getCategoryDetail(int id);
// Update opreations
Future<DataResponse>updateProject(int projectId,ProjectModel project);
Future<DataResponse>updateTask(int taskID,TaskModel task);
Future<DataResponse>updateCategory(int id, CategoryModel newCategory);
// Delete opreations
Future<DataResponse>deleteCategory(int categoryId);
Future<DataResponse>deleteTask(int taskId);
Future<DataResponse>deleteProject(int projectId);
}
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:taskino/core/data_response.dart';
import 'package:taskino/models/category_model.dart';
import 'package:taskino/models/project_model.dart';
import 'package:taskino/models/task_model.dart';
import 'package:taskino/services/database_service/database_adaptor.dart';
import 'package:taskino/services/database_service/sql_query.dart';
class AppDataBase implements DataBaseAdaptor {
/// singleton pattern
AppDataBase._internal() {
if (_database == null) database;
}
static final AppDataBase instance = AppDataBase._internal();
/// sqflite datbase instance
static Database? _database;
/// gets database instance
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDB();
return _database!;
}
/// initialize the database
_initDB() async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, 'taskino.db');
return await openDatabase(path,
version: 1, onCreate: _onCreate, onConfigure: _onConfigure);
}
///function to create tables on database created
///at result would create PROJECT,TASK,CATEGORY tables
Future<void> _onCreate(Database db, int version) async {
await db.execute(DatabaseQuery.instance.createProjectTableQuery);
await db.execute(DatabaseQuery.instance.createCategoryTableQuery);
await db.execute(DatabaseQuery.instance.createTaskTableQuery);
}
/// enables the ForeignKey capability
Future<void> _onConfigure(Database db) async {
await db.execute("PRAGMA foreign_keys = ON");
}
//<----------------------CREATE------------------------------->//
/// create project
/// returns true if opreation success
/// returns error message if opreation fail
@override
Future<DataResponse> createProject(ProjectModel project) async {
try {
if (_database == null) await database;
int id = await _database!
.insert(DatabaseQuery.instance.projectTable, project.toDBmodel());
if (project.tasks != null) {
if (project.tasks!.isNotEmpty) {
for (TaskModel taskModel in project.tasks!) {
Map<String, dynamic> dataToJson = taskModel.toJson()
..addAll({'project': id});
await _database!
.insert(DatabaseQuery.instance.taskTable, dataToJson);
}
}
}
return DataResponse(data: true, status: OpreationStatus.success);
} catch (e) {
return DataResponse(data: e.toString(), status: OpreationStatus.fail);
}
}
/// adds `Category` to category table
/// returns ture if opreation success
/// returns error string if opreation fail
@override
Future<DataResponse> createCategory(CategoryModel category) async {
try {
if (_database == null) await database;
await _database!
.insert(DatabaseQuery.instance.categoryTable, category.toDBModel());
return DataResponse(
data: true,
status: OpreationStatus.success,
);
} catch (e) {
return DataResponse(
data: e.toString(),
status: OpreationStatus.fail,
);
}
}
/// creates `task` in crosponding project
/// returns `true` if opreation is **success**
/// returns `error message` if opreation is **fail**
@override
Future<DataResponse> createTask(TaskModel task) async {
try {
if (_database == null) await database;
await _database!.insert(DatabaseQuery.instance.taskTable, task.toJson());
return DataResponse(data: true, status: OpreationStatus.success);
} catch (e) {
return DataResponse(data: e.toString(), status: OpreationStatus.fail);
}
}
//<----------------------READ------------------------------->//
/// gets all categories from database
/// returns list of `CategoryModel` if succcess
/// return error message if fai
@override
Future<DataResponse> getAllCategories() async {
try {
if (_database == null) await database;
List<Map<String, dynamic>> result = await _database!.query(
DatabaseQuery.instance.categoryTable,
);
List<CategoryModel> catgories =
result.map((e) => CategoryModel.fromJson(e)).toList();
return DataResponse(data: catgories, status: OpreationStatus.success);
} catch (e) {
return DataResponse(data: e.toString(), status: OpreationStatus.fail);
}
}
/// get all projects from database
/// returns list of `ProjectModel` if success
/// returns error message if fails
@override
Future<DataResponse> getAllProjects() async {
try {
if (_database == null) await database;
List<Map<String, dynamic>> rawResult =
await _database!.query(DatabaseQuery.instance.projectTable);
List<ProjectModel> projects =
rawResult.map((e) => ProjectModel.fromJson(e)).toList();
return DataResponse(data: projects, status: OpreationStatus.success);
} catch (e) {
return DataResponse(data: e.toString(), status: OpreationStatus.fail);
}
}
/// retrive the category detail from database
/// returns `CategoryModel` if success
/// returns error message if fail
@override
Future<DataResponse> getCategoryDetail(int id) async {
try {
if (_database == null) await database;
List<Map<String, dynamic>> rawresult = await _database!.query(
DatabaseQuery.instance.categoryTable,
where: '${CategoryModel().idFeild}=?',
whereArgs: [id],
);
CategoryModel category = CategoryModel.fromJson(
rawresult.first,
);
return DataResponse(
data: category,
status: OpreationStatus.success,
);
} catch (e) {
return DataResponse(
data: e.toString(),
status: OpreationStatus.fail,
);
}
}
/// retrive projectDetail base on id pass
/// return `ProjectModel` if it success
/// return error message if it fail
@override
Future<DataResponse> getProjectDetail(int projectId) async {
try {
List<TaskModel>? projectTasks;
ProjectModel project;
if (_database == null) await database;
// gets raw project data from db
List<Map<String, dynamic>> rawProject = await _database!.query(
DatabaseQuery.instance.projectTable,
where: '${ProjectModel().id}=?',
whereArgs: [projectId]);
// convert the json to project model
project = ProjectModel.fromJson(rawProject.first);
// gets list of tasks with same project id
List<Map<String, dynamic>> rawTasks = await _database!.query(
DatabaseQuery.instance.taskTable,
where: '${TaskModel().projectIdFeild}=?',
whereArgs: [projectId]);
if (rawTasks != null && rawTasks.isNotEmpty) {
// converts json to task model
projectTasks = rawTasks.map((e) => TaskModel.fromJson(e)).toList();
// add qured tasks to project model
project.tasks = projectTasks;
// return project model with taks if they exists
return DataResponse(data: project, status: OpreationStatus.success);
} else {
project.tasks = [];
return DataResponse(data: project, status: OpreationStatus.success);
}
} catch (e) {
return DataResponse(data: e.toString(), status: OpreationStatus.fail);
}
}
/// retrive the task detail from database
/// return `task`model if success
/// return error message if fail
@override
Future<DataResponse> getTaskDetail(int taskId) async {
try {
if (_database == null) await database;
List<Map<String, dynamic>> rawTask = await _database!.query(
DatabaseQuery.instance.taskTable,
where: '${TaskModel().idFeild}=?',
whereArgs: [taskId]);
TaskModel task = TaskModel.fromJson(rawTask.first);
return DataResponse(data: task, status: OpreationStatus.success);
} catch (e) {
return DataResponse(data: e.toString(), status: OpreationStatus.fail);
}
}
//<----------------------UPDATE------------------------------->//
@override
Future<DataResponse> updateProject(int projectId, ProjectModel project) {
// TODO: implement updateProject
throw UnimplementedError();
}
@override
Future<DataResponse> updateTask(int taskID, TaskModel task) {
// TODO: implement updateTask
throw UnimplementedError();
}
@override
Future<DataResponse> updateCategory(int id, CategoryModel newCategory) {
// TODO: implement updateCategory
throw UnimplementedError();
}
//<----------------------DELETE------------------------------->//
/// deletes the category based on id
/// returns true if success
/// returns error messaege if fail
@override
Future<DataResponse> deleteCategory(int categoryId) async {
try {
if (_database == null) await database;
await _database!.delete(DatabaseQuery.instance.categoryTable,
where: '${CategoryModel().idFeild}=?', whereArgs: [categoryId]);
return DataResponse(data: true, status: OpreationStatus.success);
} catch (e) {
return DataResponse(data: e.toString(), status: OpreationStatus.fail);
}
}
/// deletes project from DB
/// returns true if success
/// returns error message if fails
@override
Future<DataResponse> deleteProject(int projectId) async {
try {
if (_database == null) await database;
await _database!.delete(DatabaseQuery.instance.projectTable,
where: '${ProjectModel().idFeild}=?', whereArgs: [projectId]);
return DataResponse(data: true, status: OpreationStatus.success);
} catch (e) {
return DataResponse(data: e.toString(), status: OpreationStatus.fail);
}
}
/// deletes task from DB
/// returns true if success
/// returns error message if fail
@override
Future<DataResponse> deleteTask(int taskId) async {
try {
if (_database == null) await database;
await _database!.delete(DatabaseQuery.instance.taskTable,
where: '${TaskModel().idFeild}=?', whereArgs: [taskId]);
return DataResponse(data: true, status: OpreationStatus.success);
} catch (e) {
return DataResponse(data: e.toString(), status: OpreationStatus.fail);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment