Коммит d1ebe2c1 создал по автору Красавин Никита Сергеевич's avatar Красавин Никита Сергеевич
Просмотр файлов

Merge branch 'sqlite3_flutter_libs_aurora_impl' into 'main'

[feature] sqlite3_flutter_libs aurora impl

See merge request oss/flutter/flutter-community-plugins/sqlite3.dart!1
владельцы b9fb48fd dd95a19e
.DS_Store
.dart_tool/
.vscode/
.packages
.pub/
......
......@@ -12,6 +12,29 @@ Additionally, it ships the `fts5` module by default (the `json1` module is part
of the default build in recent sqlite3 versions).
No other modules are included in these builds.
## Usage on Aurora
It is sufficient to include the sqlite3_flutter_libs package in your pubspec file in order to use sqflite_common_files with a selected version of the libsqlite3 library.
**pubspec.yaml**
@todo add tag to ref for git after release
```yaml
dependencies:
sqflite_common_ffi: ^2.0.0
sqlite3_flutter_libs:
git:
url: https://gitlab.com/omprussia/flutter/flutter-community-plugins/sqlite3.dart.git
ref: 0.5.24
path: sqlite3_flutter_libs/
```
***.desktop**
```desktop
Permissions=UserDirs
```
## Notes on Android
### Included platforms
......
# SPDX-FileCopyrightText: Copyright 2024 Open Mobile Platform LLC <community@omp.ru>
# SPDX-FileCopyrightText: Copyright 2020 Simon Binder
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.10)
set(PROJECT_NAME sqlite3_lib)
set(PLUGIN_NAME sqlite3_flutter_libs)
project(${PROJECT_NAME} LANGUAGES C)
include(FetchContent)
set(SQL_LIB_NAME sqlite3_lib)
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
# cmake 3.24.0 added the `DOWNLOAD_EXTRACT_TIMESTAMP` and prints an ugly warning when
# the default is used, so override it to the recommended behavior.
# We can't really ask users to use a cmake that recent, so there's this if here.
FetchContent_Declare(
${SQL_LIB_NAME}
URL https://sqlite.org/2024/sqlite-autoconf-3460000.tar.gz
DOWNLOAD_EXTRACT_TIMESTAMP NEW
)
else()
FetchContent_Declare(
${SQL_LIB_NAME}
URL https://sqlite.org/2024/sqlite-autoconf-3460000.tar.gz
)
endif()
FetchContent_MakeAvailable(${SQL_LIB_NAME})
add_library(${PLUGIN_NAME} SHARED
"${sqlite3_lib_SOURCE_DIR}/sqlite3.c"
)
target_compile_definitions(${PLUGIN_NAME} PUBLIC DART_SHARED_LIB)
target_include_directories(${PLUGIN_NAME} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/${sqlite3_lib_SOURCE_DIR}"
)
set_target_properties(${PLUGIN_NAME} PROPERTIES
PUBLIC_HEADER "${sqlite3_lib_SOURCE_DIR}/sqlite3.h"
OUTPUT_NAME "sqlite3"
)
# Note: Keep in sync with https://github.com/simolus3/sqlite-native-libraries/blob/master/sqlite3-native-library/cpp/CMakeLists.txt
target_compile_definitions(${PLUGIN_NAME} PRIVATE
SQLITE_ENABLE_DBSTAT_VTAB
SQLITE_ENABLE_FTS5
SQLITE_ENABLE_RTREE
SQLITE_DQS=0
SQLITE_DEFAULT_MEMSTATUS=0
SQLITE_TEMP_STORE=2
SQLITE_MAX_EXPR_DEPTH=0
SQLITE_STRICT_SUBTYPE=1
SQLITE_OMIT_AUTHORIZATION
SQLITE_OMIT_DECLTYPE
SQLITE_OMIT_DEPRECATED
SQLITE_OMIT_PROGRESS_CALLBACK
SQLITE_OMIT_SHARED_CACHE
SQLITE_OMIT_TCL_VARIABLE
SQLITE_OMIT_TRACE
SQLITE_USE_ALLOCA
SQLITE_UNTESTABLE
SQLITE_HAVE_ISNAN
SQLITE_HAVE_LOCALTIME_R
SQLITE_HAVE_LOCALTIME_S
SQLITE_HAVE_MALLOC_USABLE_SIZE
SQLITE_HAVE_STRCHRNUL
)
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.vscode/
.svn/
migrate_working_dir/
android
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
pubspec.lock
#Metadata
.metadata
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
# Aurora generated
/aurora/flutter
We only have this example because otherwise `flutter packages get` in `sqlite3_flutter_libs` fails.
\ Нет новой строки в конце файла
# Sqlite3_flutter_libs example
Demonstrates how to use the sqlite3_flutter_libs plugin with sqflite_common_ffi to use a specific version of libsqlite.
## Usage
Get dependency
```shell
flutter-aurora pub get
```
Build aurora application
```shell
flutter-aurora build aurora --release
```
# SPDX-FileCopyrightText: Copyright 2024 Open Mobile Platform LLC <community@omp.ru>
# SPDX-License-Identifier: BSD-3-Clause
include: package:flutter_lints/flutter.yaml
# SPDX-FileCopyrightText: Copyright 2024 Open Mobile Platform LLC <community@omp.ru>
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.10)
project(ru.auroraos.sqlite3_flutter_libs_example LANGUAGES CXX)
include(GNUInstallDirs)
set(BINARY_NAME ${CMAKE_PROJECT_NAME})
set(FLUTTER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/flutter)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
set(CMAKE_SKIP_RPATH OFF)
set(CMAKE_INSTALL_RPATH "\$ORIGIN/../share/${BINARY_NAME}/lib")
find_package(PkgConfig REQUIRED)
pkg_check_modules(FlutterEmbedder REQUIRED IMPORTED_TARGET flutter-embedder)
add_executable(${BINARY_NAME} main.cpp ${FLUTTER_DIR}/generated_plugin_registrant.cpp)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::FlutterEmbedder)
target_include_directories(${BINARY_NAME} PRIVATE ${FLUTTER_DIR})
include(flutter/generated_plugins.cmake)
set(PACKAGE_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/${BINARY_NAME})
set(DESKTOP_INSTALL_DIR ${CMAKE_INSTALL_DATADIR}/applications)
set(ICONS_INSTALL_ROOT_DIR ${CMAKE_INSTALL_DATADIR}/icons/hicolor)
add_custom_command(TARGET ${BINARY_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libflutter-embedder.so
${PROJECT_BINARY_DIR}/bundle/lib/libflutter-embedder.so)
install(FILES ${PROJECT_BINARY_DIR}/bundle/icudtl.dat DESTINATION ${PACKAGE_INSTALL_DIR})
install(DIRECTORY ${PROJECT_BINARY_DIR}/bundle/flutter_assets DESTINATION ${PACKAGE_INSTALL_DIR})
install(DIRECTORY ${PROJECT_BINARY_DIR}/bundle/lib DESTINATION ${PACKAGE_INSTALL_DIR})
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES desktop/${BINARY_NAME}.desktop DESTINATION ${DESKTOP_INSTALL_DIR})
foreach(ICONS_SIZE 86x86 108x108 128x128 172x172)
install(FILES icons/${ICONS_SIZE}.png
RENAME ${BINARY_NAME}.png
DESTINATION ${ICONS_INSTALL_ROOT_DIR}/${ICONS_SIZE}/apps/)
endforeach(ICONS_SIZE)
[Desktop Entry]
Type=Application
Name=Sqflite
Comment=The Aurora OS example of sqflite_aurora.
Icon=ru.auroraos.sqlite3_flutter_libs_example
Exec=/usr/bin/ru.auroraos.sqlite3_flutter_libs_example
X-Nemo-Application-Type=silica-qt5
[X-Application]
Permissions=UserDirs
OrganizationName=ru.auroraos
ApplicationName=sqlite3_flutter_libs_example
/**
* SPDX-FileCopyrightText: Copyright 2024 Open Mobile Platform LLC <community@omp.ru>
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <flutter/flutter_aurora.h>
#include "generated_plugin_registrant.h"
int main(int argc, char* argv[]) {
aurora::Initialize(argc, argv);
aurora::RegisterPlugins();
aurora::Launch();
return 0;
}
%global __provides_exclude_from ^%{_datadir}/%{name}/lib/.*$
%global __requires_exclude ^lib(dconf|flutter-embedder|maliit-glib|.+_platform_plugin)\\.so.*$
Name: ru.auroraos.sqlite3_flutter_libs_example
Summary: Demonstrates how to use the sqflite_aurora plugin.
Version: 0.1.0
Release: 1
License: BSD 3-Clause
Source0: %{name}-%{version}.tar.zst
BuildRequires: cmake
BuildRequires: ninja
%description
%{summary}.
%prep
%autosetup
%build
%cmake -GNinja -DCMAKE_BUILD_TYPE=%{_flutter_build_type} -DPSDK_VERSION=%{_flutter_psdk_version} -DPSDK_MAJOR=%{_flutter_psdk_major}
%ninja_build
%install
%ninja_install
%files
%{_bindir}/%{name}
%{_datadir}/%{name}/*
%{_datadir}/applications/%{name}.desktop
%{_datadir}/icons/hicolor/*/apps/%{name}.png
// SPDX-FileCopyrightText: Copyright 2024 Open Mobile Platform LLC <community@omp.ru>
// SPDX-License-Identifier: BSD-3-Clause
import 'package:flutter/material.dart';
import 'package:internal_aurora/list_button.dart';
import 'package:internal_aurora/theme/colors.dart';
import 'plugin_impl.dart';
/// Keys form demo
enum FormTypeKeys { insert, update }
/// Form focus input
class FormWidget extends StatefulWidget {
const FormWidget({super.key, required this.impl, required this.type});
final PluginImpl impl;
final FormTypeKeys type;
@override
State<FormWidget> createState() => _FormWidgetState();
}
class _FormWidgetState extends State<FormWidget> {
final _formKey = GlobalKey<FormState>();
bool _errorUpdate = false;
final TextEditingController _idEdit = TextEditingController();
final TextEditingController _intEdit = TextEditingController();
final TextEditingController _doubleEdit = TextEditingController();
final TextEditingController _stringEdit = TextEditingController();
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/// Field ID
if (widget.type == FormTypeKeys.update)
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: TextFormField(
controller: _idEdit,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Specify "${ValueKeys.id.name.toUpperCase()}"',
),
validator: (value) {
if (_errorUpdate) {
return '${ValueKeys.id.name.toUpperCase()} not found.';
}
if (int.tryParse(value ?? '') == null) {
return 'The parameter type must be "${ValueKeys.int.name}"';
}
return null;
},
),
),
/// Field ValueKeys.int
TextFormField(
controller: _intEdit,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Specify type "${ValueKeys.int.name}"',
),
validator: (value) {
if (int.tryParse(value ?? '') == null) {
return 'The parameter type must be "${ValueKeys.int.name}"';
}
return null;
},
),
const SizedBox(height: 16.0),
/// Field ValueKeys.double
TextFormField(
controller: _doubleEdit,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Specify type "${ValueKeys.double.name}"',
),
validator: (value) {
if (double.tryParse(value?.replaceAll(',', '.') ?? '') == null) {
return 'The parameter type must be "${ValueKeys.double.name}"';
}
return null;
},
),
const SizedBox(height: 16),
/// Field ValueKeys.string
TextFormField(
controller: _stringEdit,
decoration: InputDecoration(
labelText: 'Specify type "${ValueKeys.string.name}"',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'The parameter "${ValueKeys.string.name}" not must be empty.';
}
if (value.length > 10) {
return 'The parameter "${ValueKeys.string.name}" max length 10 symbols.';
}
return null;
},
),
const SizedBox(height: 16.0),
/// Button submit
ListButton(
'${widget.type.name} data',
InternalColors.green,
onPressed: () async {
// Clear error update
_errorUpdate = false;
// Validate all form
if (_formKey.currentState?.validate() == true) {
// Get values
final id = _idEdit.text;
final valueInt = _intEdit.text;
final valueDouble = _doubleEdit.text.replaceAll(',', '.');
final valueString = _stringEdit.text;
// Update database data
if (widget.type == FormTypeKeys.insert) {
await widget.impl.insert(
valueInt: int.parse(valueInt),
valueDouble: double.parse(valueDouble),
valueString: valueString,
);
}
if (widget.type == FormTypeKeys.update) {
// Update with result
_errorUpdate = !await widget.impl.update(
id: int.parse(id),
valueInt: int.parse(valueInt),
valueDouble: double.parse(valueDouble),
valueString: valueString,
);
// Validate after update
_formKey.currentState?.validate();
}
// If not error update clear form
if (!_errorUpdate) {
// Clear form
_idEdit.clear();
_intEdit.clear();
_doubleEdit.clear();
_stringEdit.clear();
// Close keyboard
if (context.mounted) FocusScope.of(context).unfocus();
}
}
setState(() {});
},
),
],
),
);
}
}
// SPDX-FileCopyrightText: Copyright 2024 Open Mobile Platform LLC <community@omp.ru>
// SPDX-License-Identifier: BSD-3-Clause
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:internal_aurora/list_button.dart';
import 'package:internal_aurora/list_item_data.dart';
import 'package:internal_aurora/list_item_info_result.dart';
import 'package:internal_aurora/list_item_info.dart';
import 'package:internal_aurora/list_separated.dart';
import 'package:internal_aurora/theme/colors.dart';
import 'package:internal_aurora/theme/theme.dart';
import 'form_widget.dart';
import 'plugin_impl.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final PluginImpl _impl = PluginImpl();
final ScrollController _scroll = ScrollController();
bool? _dataIsEmpty;
bool? _showSuccess;
@override
void initState() {
super.initState();
_impl.isEmptyStream().listen((event) {
// Update data is empty
setState(() => _dataIsEmpty = event);
// Check is not init show success
if (_showSuccess != null) {
setState(() {
_showSuccess = true;
_scroll.animateTo(
_scroll.position.minScrollExtent,
curve: Curves.easeOut,
duration: const Duration(milliseconds: 500),
);
Future.delayed(const Duration(seconds: 2), () => setState(() => _showSuccess = false));
});
} else {
_showSuccess = false;
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: internalTheme,
home: Scaffold(
appBar: AppBar(
title: const Text('Sqflite'),
),
body: ListSeparated(
controller: _scroll,
children: [
const ListItemInfo("""
SQLite plugin for Flutter. Supports iOS, Android, MacOS
and Aurora OS.
"""),
/// Success update data
if (_showSuccess == true) const ListItemInfoSuccess('Data updated successfully!'),
/// Button for clear Sqflite
if (_dataIsEmpty == false && _showSuccess != true)
ListButton(
'Clear data',
InternalColors.coal,
onPressed: () async => await _impl.clear(),
),
/// Show list date Sqflite
ListItemData(
'Save Data',
InternalColors.purple,
description: 'Data saved via form in Sqflite.',
future: _impl.getValues(),
builder: (value) {
if (value == null) {
return 'EMPTY';
}
return SizedBox(
width: double.infinity,
child: Card(
child: DataTable(
horizontalMargin: 16,
columnSpacing: 6,
columns: ['Name', 'Value']
.map((name) => DataColumn(
label: Expanded(
child: Text(name, style: const TextStyle(fontStyle: FontStyle.italic)),
),
))
.toList(),
rows: [
for (final key in value.keys)
DataRow(
cells: <DataCell>[
DataCell(Text(key.name)),
DataCell(Text(value[key].toString())),
],
),
],
),
),
);
},
),
/// Insert form
if (_dataIsEmpty == true)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Divider(),
const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: ListItemInfo('Insert data via Sqflite plugin.'),
),
FormWidget(impl: _impl, type: FormTypeKeys.insert),
],
),
if (_dataIsEmpty == false)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Divider(),
const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: ListItemInfo('Update data via Sqflite plugin.'),
),
FormWidget(impl: _impl, type: FormTypeKeys.update),
],
),
],
),
),
);
}
}
// SPDX-FileCopyrightText: Copyright 2024 Open Mobile Platform LLC <community@omp.ru>
// SPDX-License-Identifier: BSD-3-Clause
import 'dart:async';
import 'package:path/path.dart' as p;
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
/// Keys form demo
enum ValueKeys { id, int, double, string }
/// Table name
const table = 'Test';
/// Main features of the plugin sqflite
class PluginImpl {
/// Get instance Database
Database? _db;
/// Stream for update values sqflite
/// from form
StreamController<bool>? _streamController;
/// Check save data to Database
Stream<bool> isEmptyStream() {
_streamController ??= StreamController<bool>(onListen: () async {
// Init db
await init();
// Check is empty
_streamController!.add(await isEmpty());
}, onCancel: () async {
// Close db
await close();
});
return _streamController!.stream;
}
/// Check is table not empty
Future<bool> isEmpty() async {
final rows = await _db?.rawQuery(
'SELECT COUNT(rowid) as count FROM $table',
);
if (rows != null && rows.isNotEmpty && rows[0].containsKey('count')) {
return rows[0]['count'] == 0;
}
return true;
}
/// Init database
Future<void> init() async {
// set up databaseFactory by databaseFactoryFfi for sqflite_common_ffi
databaseFactory = databaseFactoryFfi;
// Get a location using getDatabasesPath
var databasesPath = await getDatabasesPath();
String path = p.join(databasesPath, 'demo.db');
// Open the database
_db = await openDatabase(
path,
version: 1,
onCreate: (Database db, int version) async {
// When creating the db, create the table
await db.execute('''CREATE TABLE $table (
val_int INTEGER,
val_double REAL,
val_str TEXT
) STRICT''');
// STRICT able only for libsqlite version >= 3.37
},
);
}
/// Close database
Future<void> close() async {
await _db?.close();
}
/// Get value from Database
Future<Map<ValueKeys, dynamic>?> getValues() async {
final rows = await _db?.rawQuery('SELECT rowid as id, * FROM $table');
if (rows != null && rows.isNotEmpty && rows[0].containsKey('id')) {
return {
ValueKeys.id: rows[0]['id'],
ValueKeys.int: rows[0]['val_int'],
ValueKeys.double: rows[0]['val_double'],
ValueKeys.string: rows[0]['val_str'],
};
}
return null;
}
/// Set value to Database
Future<void> insert({
required int valueInt,
required double valueDouble,
required String valueString,
}) async {
await _db?.transaction((txn) async {
await txn.rawInsert(
'INSERT INTO $table(val_int, val_double, val_str) VALUES(?, ?, ?)',
[valueInt, valueDouble, valueString],
);
});
// After insert sqflite not empty
_streamController!.add(false);
}
/// Update values to Database
Future<bool> update({
required int id,
required int valueInt,
required double valueDouble,
required String valueString,
}) async {
try {
await _db?.transaction((txn) async {
final result = await txn.rawUpdate(
'UPDATE $table SET val_int = ?, val_double = ?, val_str = ? WHERE rowid = ?',
[valueInt, valueDouble, valueString, id],
);
if (result == 0) {
throw Exception('Nothing to update');
}
});
// After insert sqflite not empty
_streamController!.add(false);
// Update success
return true;
} catch (e) {
// Id not found
return false;
}
}
/// Clear all data table
Future<void> clear() async {
await _db?.rawDelete('DELETE FROM $table');
// After clear date sqflite is empty
_streamController!.add(true);
}
}
# SPDX-FileCopyrightText: Copyright 2024 Open Mobile Platform LLC <community@omp.ru>
# SPDX-License-Identifier: BSD-3-Clause
name: sqlite3_flutter_libs_example
description: Demonstrates how to use the sqlite3_flutter_libs plugin.
description: "The Aurora OS example of sqlite3_flutter_libs."
publish_to: 'none'
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=3.0.0 <4.0.0"
sdk: '>=3.2.2 <4.0.0'
dependencies:
flutter:
sdk: flutter
internal_aurora:
git:
url: https://gitlab.com/omprussia/flutter/flutter-community-plugins/internal_aurora.git
ref: 0.5.1
sqflite_common_ffi: ^2.0.0
path: ^1.8.3
sqlite3_flutter_libs:
# When depending on this package from a real application you should use:
# sqlite3_flutter_libs: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^4.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
# SPDX-FileCopyrightText: Copyright 2024 Open Mobile Platform LLC <community@omp.ru>
# SPDX-FileCopyrightText: Copyright 2020 Simon Binder
# SPDX-License-Identifier: BSD-3-Clause
name: sqlite3_flutter_libs
description: Flutter plugin to include native sqlite3 libraries with your app
version: 0.5.24
......@@ -26,3 +29,5 @@ flutter:
pluginClass: Sqlite3FlutterLibsPlugin
windows:
pluginClass: Sqlite3FlutterLibsPlugin
aurora:
ffiPlugin: true
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать