GithubHelp home page GithubHelp logo

tencent / wcdb Goto Github PK

View Code? Open in Web Editor NEW
10.5K 281.0 1.4K 79.44 MB

WCDB is a cross-platform database framework developed by WeChat.

License: Other

Objective-C 1.50% Objective-C++ 6.15% C++ 16.42% C 64.17% Makefile 0.02% Java 7.04% Shell 0.08% Ruby 0.07% Awk 0.01% Swift 3.80% AIDL 0.01% CMake 0.08% Kotlin 0.64% Groovy 0.03%
database android ios wechat sqlcipher sqlite windows linux macos

wcdb's Introduction

WCDB

PRs Welcome Release Version Platform Language

中文版本请参看这里

WCDB is an efficient, complete, easy-to-use mobile database framework used in the WeChat application. It's based on SQLite and SQLCipher, and supports five languages: C++, Java, Kotlin, Swift and Objective-C.

Feature

Easy-to-use

  • ORM (Object Relational Mapping): WCDB provides a flexible, easy-to-use ORM for creating tables, indices and constraints, as well as CRUD through C++/Java/Kotlin/Swift/Objc objects.
  • WINQ (WCDB language integrated query): WINQ is a native data querying capability which frees developers from writing glue code to concatenate SQL query strings.

With ORM and WINQ, you can insert, update, query and delete objects from database in one line code:

// C++
database.insertObjects<Sample>(Sample(1, "text"), myTable);
database.updateRow("text2", WCDB_FIELD(Sample::content), myTable, WCDB_FIELD(Sample::id) == 1);
auto objects = database.getAllObjects<Sample>(myTable, WCDB_FIELD(Sample::id) > 0);
database.deleteObjects(myTable, WCDB_FIELD(Sample::id) == 1);
// Java
database.insertObject(new Sample(1, "text"), DBSample.allFields(), myTable);
database.updateValue("text2", DBSample.content, myTable, DBSample.id.eq(1));
List<Sample> objects = database.getAllObjects(DBSample.allFields(), myTable, DBSample.id.gt(0));
database.deleteObjects(myTable, DBSample.id.eq(1));
// Kotlin
database.insertObject<Sample>(Sample(1, "text"), DBSample.allFields(), myTable)
database.updateValue("text2", DBSample.content, myTable, DBSample.id.eq(1))
val objects = database.getAllObjects<Sample>(DBSample.allFields(), myTable, DBSample.id.gt(0))
database.deleteObjects(myTable, DBSample.id.eq(1))
// Swift
try database.insert(Sample(id:1, content:"text"), intoTable: myTable)
try database.update(table: myTable,
                    on: Sample.Properties.content,
                    with: "text2"
                    where:Sample.Properties.id == 1)
let objects: [Sample] = try database.getObjects(fromTable: myTable,
                                                where: Sample.Properties.id > 0)
try database.delete(fromTable: myTable where: Sample.Properties.id == 1)
// Objc
[database insertObject:sample intoTable:myTable];
[database updateTable:myTable
          setProperty:Sample.content
              toValue:@"text2"
                where:Sample.id == 1];
NSArray* objects = [database getObjectsOfClass:Sample.class
                                     fromTable:myTable
                                         where:Sample.id > 0];
[database deleteFromTable:myTable where:Sample.id == 1];

Efficient

Through the framework layer and sqlcipher source optimization, WCDB have more efficient performance.

  • Multi-threaded concurrency: WCDB supports concurrent read-read and read-write access via connection pooling.
  • Deeply optimized: WCDB has deeply optimized the source code and configuration of SQLite to adapt to the development scenarios of mobile terminals. At the same time, WCDB has also been optimized for common time-consuming scenarios, such as writing data in batches.

Complete

WCDB summarizes common problems in practice to provide a more complete development experience for database development:

  • Encryption Support: WCDB supports database encryption via SQLCipher.
  • Corruption recovery: WCDB provides a built-in repair kit for database corruption recovery.
  • Anti-injection: WCDB provides a built-in protection from SQL injection.
  • Database model upgrade: The database model is bound to the class definition, so that the addition, deletion and modification of database fields are consistent with the definition of class variables.
  • Full-text search: WCDB provides an easy-to-use full-text search interface and includes tokenizers for multiple languages.
  • Data Migration: WCDB supports to migrate data from one databasse to another with simple configuration. And developers don't need to care about the intermediate status and progress of the migration.
  • Data Compression: WCDB supports to compress content via Zstd within specific fields of a database table through a simple configuration. Once configured, the details of data compression and decompression become transparent to developers, and WCDB can automatically compress existing data.

Compatibility

WCDB has interfaces in three languages: C++, Java, Kotlin, Swift, and Objc. Interfaces in different languages share the same underlying logic. The code structure of WCDB is shown in the figure below:

Under such architecture, WCDB in different languages can have the same interface structure and interface capabilities. In one project, you can write database code in different languages with one WCDB. Database logic in different languages will not conflict. Some global interfaces such as error monitoring can work on database logic in different languages at the same time.

Build and Install

Following wikies contain the detailed instructions about building and installing of WCDB.

Tutorials

Tutorials of different languages can be found below:

Contributing

If you are interested in contributing, check out the [CONTRIBUTING.md], also join our Tencent OpenSource Plan.

信息公示

wcdb's People

Contributors

chzhij5 avatar cntrump avatar codeeagle avatar crazyevent avatar drakeet avatar eltociear avatar infinnie avatar iosleep avatar john-he-928 avatar lilejia avatar lingol avatar linqingmo avatar looseyi avatar qiangxinyu avatar qiaohaijun avatar qiuwen-chen avatar ringod avatar watergear avatar wongzigii avatar x140yu avatar yizhi996 avatar zhangyanrui avatar zhongwuzw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wcdb's Issues

iOS文件编译设置

由于WCDB是基于Objective-C++,因此需要将源文件对应的后缀.m改为.mm

所以如果Message在头文件引入WCDB.h, 所有用到Message的地方都必须将源文件后缀改成.mm, 否则提示'list' file not found ??

项目编译时.hpp里有报错

Uploading WX20170616-170637.png…

statement_update.hpp
statement_select.hpp
statement_delete.hpp
三个文件都是同样的错误。

奇怪的是我新建项目测试时是正常的,还有改动了offset这个方法名之后也能编译通过

解密WCDB加密数据库失败

之前问答的issues:
#36

你好,我尝试解密数据库还是失败,烦请帮忙看一下原因,多谢!

打开wcdb加密数据库代码如下:
db = com.tencent.wcdb.database.SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(),
(isDecode ? password.getBytes() : null/* 无密 */), cipher, null,
SQLiteDatabase.OPEN_READWRITE, new DatabaseErrorHandler() {
@OverRide
public void onCorruption(com.tencent.wcdb.database.SQLiteDatabase dbObj) {
LogUtil.e(TAG, "CipherDB::startDataBaseMigration2::onCorruption1");
}
});

创建临时文件暂存代码:
newFile = File.createTempFile(ENCRYPTED_DATABASE_PREFIX, TEMP_ENCRYPTED_DATABASE_PREFIX,
context.getCacheDir());

数据迁移代码:
try {
// db.rawExecSQL("PRAGMA cipher_default_kdf_iter = 4000;");
db.execSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';",
newFile.getAbsolutePath(), (isDecode ? ""/* 无密 */ : password)));
db.execSQL("SELECT sqlcipher_export('encrypted')");
db.execSQL("DETACH DATABASE encrypted;");
db.close();
} catch (Exception e) {
LogUtil.e(TAG, "CipherDB::startDataBaseMigration OMG ...DataMigration has exception. "
+ e.getMessage());
throw new StopRequestException(DATA_TRANSFER_DATA_MIGRATION_ERROR, e);
}

异常日志,如下:

06-19 16:17:22.214 7185-7185/com.wlx.debug W/wlx: main:SqliteCipherLogic [LOGIN_READLY]: CipherDB::onItemClick: common_new
06-19 16:17:22.215 7185-7185/com.wlx.debug D/wlx: main:SqliteCipherLogic [LOGIN_READLY]: CipherDB::startDataBaseMigration starting... databaseName: common_new
06-19 16:17:22.215 7185-7185/com.wlx.debug D/wlx: main:SqliteCipherLogic [LOGIN_READLY]: CipherDB::startDataBaseMigration originalFile path: /data/user/0/com.wlx.debug/databases/common_new

06-19 16:17:22.215 7185-7185/com.wlx.debug I/WCDB.SQLiteConnectionPool: Max connection pool size is 1.
06-19 16:17:22.216 7185-7185/com.wlx.debug I/WCDB: Initialize SQLite connection module 'MMFTS'...
06-19 16:17:22.216 7185-7185/com.wlx.debug I/WCDB.SQLiteConnection: Opened connection 0x9b8f6808 with label '/data/user/0/com.wlx.debug/databases/common_new'
06-19 16:17:22.216 7185-7185/com.wlx.debug I/WCDB.SQLiteConnection: sqlite3_key verification passed.

06-19 16:17:22.254 7185-7185/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 5] statement aborts at 1: [PRAGMA journal_mode=PERSIST] database is locked
06-19 16:17:22.255 7185-7185/com.wlx.debug W/WCDB.SQLiteConnectionPool: Connections: 0 active, 0 idle, 0 available.
06-19 16:17:22.257 7185-7185/com.wlx.debug I/WCDB.SQLiteConnection: executeForString took 1ms - failed, sql="PRAGMA journal_mode=PERSIST", exception="database is locked (code 5, errno 0): "
06-19 16:17:22.257 7185-7185/com.wlx.debug W/WCDB.SQLiteConnection: Could not change the database journal mode of '/data/user/0/com.wlx.debug/databases/common_new' from 'wal' to 'PERSIST' because the database is locked. This usually means that there are other open connections to the database which prevents the database from enabling or disabling write-ahead logging mode. Proceeding without changing the journal mode.
06-19 16:17:22.258 7185-7185/com.wlx.debug D/wlx: main:SqliteCipherLogic [LOGIN_READLY]: CipherDB::startDataBaseMigration originalFile version: 65
06-19 16:17:22.266 7185-7185/com.wlx.debug D/wlx: main:SqliteCipherLogic [LOGIN_READLY]: CipherDB::startDataBaseMigration newFile path: /data/user/0/com.wlx.debug/cache/tmp_common

06-19 16:17:23.852 7185-7185/com.wlx.debug I/WCDB.SQLiteConnection: executeForChangedRowCount took 1584ms - failed, sql="SELECT sqlcipher_export('encrypted')", exception="unknown error (code 0, errno -1): Queries can be performed using SQLiteDatabase query or rawQuery methods only.", changedRows=0

06-19 16:17:23.852 7185-7185/com.wlx.debug E/wlx: main:SqliteCipherLogic [LOGIN_READLY]: CipherDB::startDataBaseMigration OMG ...DataMigration has exception. unknown error (code 0, errno -1): Queries can be performed using SQLiteDatabase query or rawQuery methods only.
06-19 16:17:23.852 7185-7185/com.wlx.debug E/wlx: main:SqliteCipherLogic [LOGIN_READLY]: CipherDB::startDataBaseMigration --- > Aborting request for database migration common_new: com.tencent.wcdb.database.SQLiteException: unknown error (code 0, errno -1): Queries can be performed using SQLiteDatabase query or rawQuery methods only.
06-19 16:17:23.853 7185-7185/com.wlx.debug D/wlx: main:SqliteCipherLogic [LOGIN_READLY]: CipherDB::startDataBaseMigration finally --- > 103

独立编译tokenizer的问题

用的是cmake编译的源码。
脚本

cmake_minimum_required(VERSION 3.4.1)
project(icucompat C CXX)

aux_source_directory(${ICU_COMPAT_DIR} ICU_COMPAT_DIR)

INCLUDE_DIRECTORIES(${ICU_COMPAT_DIR})
INCLUDE_DIRECTORIES(${ICU_COMPAT_DIR}/unicode)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_REENTRANT \
-Wall -Werror -ffunction-sections -fdata-sections \
-DSQLITE_HAS_CODEC -DSQLITE_CORE -DSQLITE_OS_UNIX")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPIC -fPIC")

add_library(icucompat STATIC ${ICU_COMPAT_DIR})

报错

error: undefined reference to 'utf8_nextCharSafeBody_50'
error: undefined reference to 'ubrk_open_50'
error: undefined reference to 'ubrk_first_50'
error: undefined reference to 'ubrk_current_50'
error: undefined reference to 'ubrk_next_50'
error: undefined reference to 'ubrk_getRuleStatus_50'
error: undefined reference to 'u_isspace_50'
error: undefined reference to 'ubrk_next_50'
error: undefined reference to 'ubrk_getRuleStatus_50'
error: undefined reference to 'ubrk_isBoundary_50'
error: undefined reference to 'ubrk_close_50'
error: undefined reference to 'unorm_normalize_50'
error: undefined reference to 'u_strFoldCase_50'
error: undefined reference to 'u_strToUTF8_50'
error: undefined reference to 'u_strToUTF8_50'

Android集成WCDB后性能问题

你好,我们的应用会在启动后内存维护唯一的SQLiteOpenHelper对象,SQLiteOpenHelper对象中有个全局成员是SQLiteDatabase,当多线程调用增删改查时候都使用唯一的SQLiteDatabase操作。

SQLiteOpenHelper对象内部维护SQLiteDatabase全局成员,如下:
public SQLiteDatabase open() throws SQLException {
if (null == db || !db.isOpen()) {
db = getWritableDatabase();
}
return db;
}

创建数据库cipher配置,如下:
private static final SQLiteCipherSpec cipher = new SQLiteCipherSpec().setPageSize(1024).setSQLCipherVersion(1);

【问题】切换WCDB后性能并没有提高,反而还有下降,原来我们业务完成操作数据库耗时17s左右,目前WCDB耗时接近33s左右,请问是哪里没有配置对?还是其他原因呢?感谢!!!

另,个人理解原生数据库读写是单队列的,WCDB读写支持并发,所有想知道如何使用才能实现读写并发呢?

使用新版Android Studio编译时log记录报错误

Message界面报错:Error:Failed to notify project evaluation listener.
log报错误:
org.gradle.tooling.BuildException: Could not run build action using Gradle distribution 'https://services.gradle.org/distributions/gradle-3.3-all.zip'.
at org.gradle.tooling.internal.consumer.ExceptionTransformer.transform(ExceptionTransformer.java:51)
at org.gradle.tooling.internal.consumer.ExceptionTransformer.transform(ExceptionTransformer.java:29)
at org.gradle.tooling.internal.consumer.ResultHandlerAdapter.onFailure(ResultHandlerAdapter.java:41)
at org.gradle.tooling.internal.consumer.async.DefaultAsyncConsumerActionExecutor$1$1.run(DefaultAsyncConsumerActionExecutor.java:57)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.gradle.tooling.internal.consumer.BlockingResultHandler.getResult(BlockingResultHandler.java:46)
at org.gradle.tooling.internal.consumer.DefaultBuildActionExecuter.run(DefaultBuildActionExecuter.java:48)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.doResolveProjectInfo(GradleProjectResolver.java:217)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.access$200(GradleProjectResolver.java:72)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver$ProjectConnectionDataNodeFunction.fun(GradleProjectResolver.java:765)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver$ProjectConnectionDataNodeFunction.fun(GradleProjectResolver.java:749)
at org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper.execute(GradleExecutionHelper.java:227)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.resolveProjectInfo(GradleProjectResolver.java:112)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.resolveProjectInfo(GradleProjectResolver.java:72)
at com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolverImpl.lambda$resolveProjectInfo$0(RemoteExternalSystemProjectResolverImpl.java:37)
at com.intellij.openapi.externalSystem.service.remote.AbstractRemoteExternalSystemService.execute(AbstractRemoteExternalSystemService.java:59)
at com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolverImpl.resolveProjectInfo(RemoteExternalSystemProjectResolverImpl.java:37)
at com.intellij.openapi.externalSystem.service.remote.wrapper.ExternalSystemProjectResolverWrapper.resolveProjectInfo(ExternalSystemProjectResolverWrapper.java:49)
at com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolveProjectTask.doExecute(ExternalSystemResolveProjectTask.java:51)
at com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask.execute(AbstractExternalSystemTask.java:138)
at com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask.execute(AbstractExternalSystemTask.java:124)
at com.intellij.openapi.externalSystem.util.ExternalSystemUtil$3.execute(ExternalSystemUtil.java:415)
at com.intellij.openapi.externalSystem.util.ExternalSystemUtil$5.run(ExternalSystemUtil.java:494)
at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:635)
at com.intellij.openapi.progress.impl.CoreProgressManager$3.run(CoreProgressManager.java:170)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:494)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:443)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:54)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:155)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$1.run(ProgressManagerImpl.java:128)
at com.intellij.openapi.application.impl.ApplicationImpl$2.run(ApplicationImpl.java:307)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.gradle.internal.exceptions.LocationAwareException: A problem occurred configuring project ':wcdb'.
at org.gradle.initialization.DefaultExceptionAnalyser.transform(DefaultExceptionAnalyser.java:74)
at org.gradle.initialization.MultipleBuildFailuresExceptionAnalyser.transform(MultipleBuildFailuresExceptionAnalyser.java:47)
at org.gradle.initialization.StackTraceSanitizingExceptionAnalyser.transform(StackTraceSanitizingExceptionAnalyser.java:30)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:122)
at org.gradle.initialization.DefaultGradleLauncher.getBuildAnalysis(DefaultGradleLauncher.java:107)
at org.gradle.launcher.exec.GradleBuildController.configure(GradleBuildController.java:79)
at org.gradle.tooling.internal.provider.runner.ClientProvidedBuildActionRunner.run(ClientProvidedBuildActionRunner.java:60)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:43)
at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:40)
at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:75)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:44)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:29)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:47)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
at org.gradle.util.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':wcdb'.
at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:94)
at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:89)
at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:76)
at org.gradle.configuration.project.LifecycleProjectEvaluator.access$000(LifecycleProjectEvaluator.java:33)
at org.gradle.configuration.project.LifecycleProjectEvaluator$1.execute(LifecycleProjectEvaluator.java:53)
at org.gradle.configuration.project.LifecycleProjectEvaluator$1.execute(LifecycleProjectEvaluator.java:50)
at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)
at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:50)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:628)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:129)
at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
at org.gradle.initialization.DefaultGradleLauncher$1.execute(DefaultGradleLauncher.java:161)
at org.gradle.initialization.DefaultGradleLauncher$1.execute(DefaultGradleLauncher.java:158)
at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:158)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:119)
... 44 more
Caused by: org.gradle.internal.event.ListenerNotificationException: Failed to notify project evaluation listener.
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:55)
at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:79)
at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:30)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy16.afterEvaluate(Unknown Source)
at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:82)
... 64 more
Caused by: java.lang.NullPointerException
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:210)
at com.android.build.gradle.internal.ndk.NdkHandler.getPlatformVersion(NdkHandler.java:145)
at com.android.build.gradle.internal.ndk.NdkHandler.supports64Bits(NdkHandler.java:291)
at com.android.build.gradle.internal.ndk.NdkHandler.getSupportedAbis(NdkHandler.java:354)
at com.android.build.gradle.tasks.ExternalNativeJsonGenerator.create(ExternalNativeJsonGenerator.java:571)
at com.android.build.gradle.internal.TaskManager.createExternalNativeBuildJsonGenerators(TaskManager.java:1241)
at com.android.build.gradle.internal.LibraryTaskManager.lambda$createTasksForVariantData$11(LibraryTaskManager.java:240)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.internal.LibraryTaskManager.createTasksForVariantData(LibraryTaskManager.java:235)
at com.android.build.gradle.internal.VariantManager.createTasksForVariantData(VariantManager.java:460)
at com.android.build.gradle.internal.VariantManager.lambda$createAndroidTasks$1(VariantManager.java:282)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.internal.VariantManager.createAndroidTasks(VariantManager.java:278)
at com.android.build.gradle.BasePlugin.lambda$createAndroidTasks$6(BasePlugin.java:601)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:596)
at com.android.build.gradle.BasePlugin.lambda$null$4(BasePlugin.java:526)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.lambda$createTasks$5(BasePlugin.java:522)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:93)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:82)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:44)
... 69 more
2017-06-13 15:31:56,047 [ 51283] WARN - nal.AbstractExternalSystemTask - Failed to notify project evaluation listener.
com.intellij.openapi.externalSystem.model.ExternalSystemException: Failed to notify project evaluation listener.
at com.android.tools.idea.gradle.project.sync.idea.ProjectImportErrorHandler.getUserFriendlyError(ProjectImportErrorHandler.java:86)
at com.android.tools.idea.gradle.project.sync.idea.AndroidGradleProjectResolver.getUserFriendlyError(AndroidGradleProjectResolver.java:361)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver$ProjectConnectionDataNodeFunction.fun(GradleProjectResolver.java:769)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver$ProjectConnectionDataNodeFunction.fun(GradleProjectResolver.java:749)
at org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper.execute(GradleExecutionHelper.java:227)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.resolveProjectInfo(GradleProjectResolver.java:112)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.resolveProjectInfo(GradleProjectResolver.java:72)
at com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolverImpl.lambda$resolveProjectInfo$0(RemoteExternalSystemProjectResolverImpl.java:37)
at com.intellij.openapi.externalSystem.service.remote.AbstractRemoteExternalSystemService.execute(AbstractRemoteExternalSystemService.java:59)
at com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolverImpl.resolveProjectInfo(RemoteExternalSystemProjectResolverImpl.java:37)
at com.intellij.openapi.externalSystem.service.remote.wrapper.ExternalSystemProjectResolverWrapper.resolveProjectInfo(ExternalSystemProjectResolverWrapper.java:49)
at com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolveProjectTask.doExecute(ExternalSystemResolveProjectTask.java:51)
at com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask.execute(AbstractExternalSystemTask.java:138)
at com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask.execute(AbstractExternalSystemTask.java:124)
at com.intellij.openapi.externalSystem.util.ExternalSystemUtil$3.execute(ExternalSystemUtil.java:415)
at com.intellij.openapi.externalSystem.util.ExternalSystemUtil$5.run(ExternalSystemUtil.java:494)
at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:635)
at com.intellij.openapi.progress.impl.CoreProgressManager$3.run(CoreProgressManager.java:170)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:494)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:443)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:54)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:155)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$1.run(ProgressManagerImpl.java:128)
at com.intellij.openapi.application.impl.ApplicationImpl$2.run(ApplicationImpl.java:307)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.gradle.internal.event.ListenerNotificationException: Failed to notify project evaluation listener.
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:55)
at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:79)
at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:30)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy16.afterEvaluate(Unknown Source)
at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:82)
at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:76)
at org.gradle.configuration.project.LifecycleProjectEvaluator.access$000(LifecycleProjectEvaluator.java:33)
at org.gradle.configuration.project.LifecycleProjectEvaluator$1.execute(LifecycleProjectEvaluator.java:53)
at org.gradle.configuration.project.LifecycleProjectEvaluator$1.execute(LifecycleProjectEvaluator.java:50)
at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)
at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:50)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:628)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:129)
at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
at org.gradle.initialization.DefaultGradleLauncher$1.execute(DefaultGradleLauncher.java:161)
at org.gradle.initialization.DefaultGradleLauncher$1.execute(DefaultGradleLauncher.java:158)
at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:158)
at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:119)
at org.gradle.initialization.DefaultGradleLauncher.getBuildAnalysis(DefaultGradleLauncher.java:107)
at org.gradle.launcher.exec.GradleBuildController.configure(GradleBuildController.java:79)
at org.gradle.tooling.internal.provider.runner.ClientProvidedBuildActionRunner.run(ClientProvidedBuildActionRunner.java:60)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:43)
at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:40)
at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:75)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:44)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:29)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:47)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
at org.gradle.util.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: java.lang.NullPointerException
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:210)
at com.android.build.gradle.internal.ndk.NdkHandler.getPlatformVersion(NdkHandler.java:145)
at com.android.build.gradle.internal.ndk.NdkHandler.supports64Bits(NdkHandler.java:291)
at com.android.build.gradle.internal.ndk.NdkHandler.getSupportedAbis(NdkHandler.java:354)
at com.android.build.gradle.tasks.ExternalNativeJsonGenerator.create(ExternalNativeJsonGenerator.java:571)
at com.android.build.gradle.internal.TaskManager.createExternalNativeBuildJsonGenerators(TaskManager.java:1241)
at com.android.build.gradle.internal.LibraryTaskManager.lambda$createTasksForVariantData$11(LibraryTaskManager.java:240)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.internal.LibraryTaskManager.createTasksForVariantData(LibraryTaskManager.java:235)
at com.android.build.gradle.internal.VariantManager.createTasksForVariantData(VariantManager.java:460)
at com.android.build.gradle.internal.VariantManager.lambda$createAndroidTasks$1(VariantManager.java:282)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.internal.VariantManager.createAndroidTasks(VariantManager.java:278)
at com.android.build.gradle.BasePlugin.lambda$createAndroidTasks$6(BasePlugin.java:601)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:596)
at com.android.build.gradle.BasePlugin.lambda$null$4(BasePlugin.java:526)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.lambda$createTasks$5(BasePlugin.java:522)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:93)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:82)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:44)
... 69 more

请问是什么原因?自查了网上的部分解决方法,删dist下文件、重启电脑都无效。

Android创建数据库表失败

你好,我的应用启动会创建common_new的数据库,数据库中有2个表user、logo。目前切换到WCDB后创建表失败,请问是为什么?日志如下,多谢!

06-13 17:35:02.153 16576-16712/com.wlx.debug I/WCDB: Initialize JNI module (1/11) CursorWindow...
06-13 17:35:02.153 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/CursorWindow natives
06-13 17:35:02.154 16576-16712/ccom.wlx.debug I/WCDB: Initialize JNI module (2/11) FileUtils...
06-13 17:35:02.154 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/FileUtils natives
06-13 17:35:02.154 16576-16712/com.wlx.debug I/WCDB: Initialize JNI module (3/11) ChunkedCursorWindow...
06-13 17:35:02.154 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/database/ChunkedCursorWindow natives
06-13 17:35:02.154 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/database/SQLiteAsyncQuery natives
06-13 17:35:02.154 16576-16712/com.wlx.debug I/WCDB: Initialize JNI module (4/11) SQLiteConnection...
06-13 17:35:02.154 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/database/SQLiteConnection natives
06-13 17:35:02.154 16576-16712/com.wlx.debug I/WCDB: Initialize JNI module (5/11) SQLiteDebug...
06-13 17:35:02.154 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/database/SQLiteDebug natives
06-13 17:35:02.155 16576-16712/com.wlx.debug I/WCDB: Initialize JNI module (6/11) SQLiteDirectCursor...
06-13 17:35:02.155 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/database/SQLiteDirectQuery natives
06-13 17:35:02.155 16576-16712/com.wlx.debug I/WCDB: Initialize JNI module (7/11) SQLiteGlobal...
06-13 17:35:02.155 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/database/SQLiteGlobal natives
06-13 17:35:02.155 16576-16712/com.wlx.debug I/WCDB: Initialize JNI module (8/11) DBBackup...
06-13 17:35:02.155 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/repair/BackupKit natives
06-13 17:35:02.155 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/repair/RecoverKit natives
06-13 17:35:02.155 16576-16712/com.wlx.debug I/WCDB: Initialize JNI module (9/11) DBDumpUtil...
06-13 17:35:02.157 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/repair/DBDumpUtil natives
06-13 17:35:02.157 16576-16712/com.wlx.debug I/WCDB: Initialize JNI module (10/11) DBRepair...
06-13 17:35:02.157 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/repair/RepairKit natives
06-13 17:35:02.157 16576-16712/com.wlx.debug I/WCDB: Initialize JNI module (11/11) Log...
06-13 17:35:02.157 16576-16712/com.wlx.debug V/WCDB.JNIHelp: Registering com/tencent/wcdb/support/Log natives
06-13 17:35:02.163 16576-16712/com.wlx.debug I/WCDB.SQLiteConnectionPool: Max connection pool size is 1.
06-13 17:35:02.164 16576-16712/com.wlx.debug I/WCDB: Initialize SQLite connection module 'MMFTS'...
06-13 17:35:02.180 16576-16712/com.wlx.debug I/WCDB.SQLiteConnection: Opened connection 0xaed22608 with label '/data/data/com.wlx.debug/databases/common_new'
06-13 17:35:02.185 16576-16712/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 1] no such table: logo
06-13 17:35:02.188 16576-16712/com.wlx.debug I/WCDB.SQLiteConnection: prepare took 2ms - failed, sql="SELECT _id, from_time, to_time, add_time, image_url, image_md5, file_size FROM logo WHERE from_time<? and to_time>?", exception="no such table: logo (code 1, errno 0): , while compiling: SELECT _id, from_time, to_time, add_time, image_url, image_md5, file_size FROM logo WHERE from_time<? and to_time>?"
06-13 17:35:02.540 16576-16576/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 1] no such table: users
06-13 17:35:02.541 16576-16576/com.wlx.debug I/WCDB.SQLiteConnection: prepare took 1ms - failed, sql="select * from users where (is_login <> 2 and is_login <> 100) order by last_login_time desc", exception="no such table: users (code 1, errno 0): , while compiling: select * from users where (is_login <> 2 and is_login <> 100) order by last_login_time desc"
06-13 17:35:03.562 16576-16783/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 1] no such table: users
06-13 17:35:03.563 16576-16783/com.wlx.debug I/WCDB.SQLiteConnection: prepare took 1ms - failed, sql="select * from users where (is_login <> 2 and is_login <> 100) order by last_login_time desc", exception="no such table: users (code 1, errno 0): , while compiling: select * from users where (is_login <> 2 and is_login <> 100) order by last_login_time desc"

iOS 建议添加打包脚本

现在编译需要把真机跟模拟器的库用 lipo 合并, 有一点麻烦, 希望可以添加打包脚本, 以后升级可以方便一点。

SetGlobalTrace回调不执行

代码如下.

	NSString *path = [[self dbFilePath] stringByAppendingPathComponent:@"656.db"];
	NSFileManager* fileManager = [NSFileManager defaultManager];
	self.database = [[WCTDatabase alloc] initWithPath:path];
//	NSData *password = [@"MyPassword" dataUsingEncoding:NSASCIIStringEncoding];
//	[self.database setCipherKey:password];
	BOOL result = [self.database createTableAndIndexesOfName:@"message"
											  withClass:message.class];
	
	//Error Monitor
	[WCTStatictics SetGlobalErrorReport:^(WCTError *error) {
		NSLog(@"[WCDB]%@", error);
	}];
	
	//Performance Monitor
	[WCTStatictics SetGlobalTrace:^(WCTTag tag, NSDictionary<NSString *, NSNumber *> *sqls, NSInteger cost) {
		NSLog(@"Database with tag:%d", tag);
		NSLog(@"Run :");
		[sqls enumerateKeysAndObjectsUsingBlock:^(NSString *sqls, NSNumber *count, BOOL *) {
			NSLog(@"SQL %@ %@ times", sqls, count);
		}];
		NSLog(@"Total cost %ld nanoseconds", (long)cost);
	}];

好像WCTStatictics SetGlobalTrace不执行,是我姿势有问题么...SetGlobalErrorReport有回调,我后面触发过DB CRUD操作.

Benchmark

如果可能, 希望能在readme中增加官方的性能测试数据, 主要是以下三点:

  • 多并发数据库操作。 WCDB是支持多并发读写, 文档上说是线程安全的。 希望增加一下WCDB模式下频繁的多并发读写和传统的1写N读模式的性能对比(包括漏读和脏读的几率)?
  • WINQ性能。我去年也开源了一个小工具(无耻的蹭热点做个广告🙈:patchwork), 里边ActiveRecord模块也实现了类似WINQ的操作, 但没有用c++运算符重载方式实现(考虑过, 但是c++技能已经生疏了, 特别是c++11之后的), 不得不说, 运算符重载的实现方式对于使用者来说很简洁。 但是用函数拼装sql, 有一定的性能损耗(winq的运算符重载是const的,也就是说, 在这过程中会产生大量临时对象)。 不知道有没有一些稍微复杂sql操作的性能测试数据?
  • SQLCipher。 我们之前做过测试, sqlcipher会带来比较大的性能影响(表的行数越多,两者区别越小, 但是也几乎有40%左右的损耗 -- 但是我们没有把sqlcipher和sqlite编译在一起),不知道WCDB有没有这方面的官方测试?

集成WCDB后希望能实现解密数据库

你好,我们应用原来使用cipher android加密,现在集成了wcdb。为了方便调试问题,我们在debug版本中支持解密已经加密的数据库,请问wcdb如何将已经加密的数据库转为非加密数据库呢?

原来的方法,如下:
1.打开已经加密的数据库,创建临时文件
2.将数据迁移到临时文件(newFile就是临时文件)
// 开始数据迁移
try {
// db.rawExecSQL("PRAGMA cipher_default_kdf_iter = 4000;");
db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';",
newFile.getAbsolutePath(), (isDecode ? ""/* 无密 */ : password)));
db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
db.rawExecSQL("DETACH DATABASE encrypted;");
db.close();
} catch (Exception e) {
LogUtil.e(TAG, "CipherDB::startDataBaseMigration OMG ...DataMigration has exception. "
+ e.getMessage());
throw new StopRequestException(DATA_TRANSFER_DATA_MIGRATION_ERROR, e);
}
3.临时文件生成新数据库

表创建失败

声明类:
@interface TestWCDBObject : NSObject
@Property int localID;
@Property(retain) NSString *content;
@Property(retain) NSDate *createTime;
@Property(retain) NSDate *modifiedTime;
@Property(assign) int unused; //You can just define the properties you need

WCDB_PROPERTY(localID)
WCDB_PROPERTY(content)
WCDB_PROPERTY(createTime)
WCDB_PROPERTY(modifiedTime)
@EnD

实现类:
@implementation TestWCDBObject
WCDB_IMPLEMENTATION(TestWCDBObject)
WCDB_SYNTHESIZE(TestWCDBObject, localID)
WCDB_SYNTHESIZE(TestWCDBObject, content)
WCDB_SYNTHESIZE(TestWCDBObject, createTime)
WCDB_SYNTHESIZE(TestWCDBObject, modifiedTime)

WCDB_PRIMARY(TestWCDBObject, localID)

WCDB_INDEX(TestWCDBObject, "_index", createTime)

@EnD

创建表:
NSArray *cachPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *path = [cachPath objectAtIndex:0];
WCTDatabase database = [[WCTDatabase alloc] initWithPath:path];
/

CREATE TABLE messsage (localID INTEGER PRIMARY KEY,
content TEXT,
createTime BLOB,
modifiedTime BLOB)
*/
BOOL result = [database createTableAndIndexesOfName:@"TestWCDBObject"
withClass:TestWCDBObject.class];

result 是NO 

IOS pod 失败

$ /usr/bin/git clone https://github.com/Tencent/wcdb.git
/var/folders/j4/zzxbx4sx7071b3p5grljnqlc0000gn/T/d20170616-31076-qljeg5
--template= --single-branch --depth 1 --branch v1.0.0
Cloning into '/var/folders/j4/zzxbx4sx7071b3p5grljnqlc0000gn/T/d20170616-31076-qljeg5'...
Note: checking out 'f97a55c08d6313af8f5e6afb3e83aab523ffad8d'.

 You are in 'detached HEAD' state. You can look around, make experimental
 changes and commit them, and you can discard any commits you make in this
 state without impacting any branches by performing another checkout.
 
 If you want to create a new branch to retain commits you create, you may
 do so (now or later) by using -b with the checkout command again. Example:
 
   git checkout -b <new-branch-name>
 
 $ /usr/bin/git submodule update --init --recursive
 Submodule 'openssl' (https://github.com/openssl/openssl.git) registered for path 'openssl'
 Submodule 'sqlcipher' (https://github.com/Tencent/sqlcipher.git) registered for path 'sqlcipher'
 Cloning into '/private/var/folders/j4/zzxbx4sx7071b3p5grljnqlc0000gn/T/d20170616-31076-qljeg5/openssl'...

 error: RPC failed; curl 56 SSLRead() return error -9806
 fatal: The remote end hung up unexpectedly
 fatal: early EOF
 fatal: index-pack failed
 fatal: clone of 'https://github.com/openssl/openssl.git' into submodule path '/private/var/folders/j4/zzxbx4sx7071b3p5grljnqlc0000gn/T/d20170616-31076-qljeg5/openssl' failed
 Failed to clone 'openssl'. Retry scheduled
 Cloning into '/private/var/folders/j4/zzxbx4sx7071b3p5grljnqlc0000gn/T/d20170616-31076-qljeg5/sqlcipher'...
 error: RPC failed; curl 18 transfer closed with outstanding read data remaining
 fatal: The remote end hung up unexpectedly
 fatal: early EOF
 fatal: index-pack failed
 fatal: clone of 'https://github.com/Tencent/sqlcipher.git' into submodule path '/private/var/folders/j4/zzxbx4sx7071b3p5grljnqlc0000gn/T/d20170616-31076-qljeg5/sqlcipher' failed
 Failed to clone 'sqlcipher'. Retry scheduled
 Cloning into '/private/var/folders/j4/zzxbx4sx7071b3p5grljnqlc0000gn/T/d20170616-31076-qljeg5/openssl'...

Android从SQLCipher Android升级到WCDB失败

你好,我们应用原来已经使用SQLCipher Android对数据库进行加密,现在从老版本升级到集成了WCDB版本时候遇到了问题,出问题的数据库是common_new。

原来老版本cipher数据库配置如下:(传入密码是正确的)
private static SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {

    @Override
    public void postKey(SQLiteDatabase db) {
        LogUtil.d(TAG, "CipherDB::postKey");
    }

    @Override
    public void preKey(SQLiteDatabase db) {
        LogUtil.d(TAG, "CipherDB::preKey");
        db.rawExecSQL("PRAGMA cipher_default_kdf_iter = 4000;");
    }

};

集成WCDB新版本配置如下:(CommonSQLHelper是common_new数据库对应的SQLiteOpenHelper)
public CommonSQLHelper() {
super(MMApplication.context, SqliteCipherLogic.getCommonDatabaseName(),
SqliteCipherLogic.getCommonDBEncryptedKey().getBytes(), cipher, null, DATABASE_VERSION,
new DatabaseErrorHandler() {
@OverRide
public void onCorruption(SQLiteDatabase dbObj) {
LogUtil.e(TAG, "CipherDB::onCorruption()");
}
});
setWriteAheadLoggingEnabled(true);
LogUtil.d(TAG, "CipherDB::CommonSQLHelper()::" + SqliteCipherLogic.getCommonDatabaseName());
}

// 加密描述对象
// 如以前使用过其他PRAGMA,可添加其他选项
private static final SQLiteCipherSpec cipher = new SQLiteCipherSpec()
        .setPageSize(1024) // SQLCipher 默认 Page size 为1024
        .setSQLCipherVersion(1); // 1,2,3 分别对应 1.x, 2.x, 3.x 创建的 SQLCipher 数据库

问题日志如下:
06-15 17:48:14.570 21999-21999/com.wlx.debug D/debug: main:CommonSQLHelper [OFFLINE]: CipherDB::CommonSQLHelper()::common_new
06-15 17:48:14.572 21999-21999/com.wlx.debug I/WCDB.SQLiteConnectionPool: Max connection pool size is 4.
06-15 17:48:14.575 21999-21999/com.wlx.debug I/WCDB: Initialize SQLite connection module 'MMFTS'...
06-15 17:48:14.590 21999-21999/com.wlx.debug I/WCDB.SQLiteConnection: Opened connection 0xb0562008 with label '/data/user/0/com.wlx.debug/databases/common_new'
06-15 17:48:14.591 21999-21999/com.wlx.debug I/WCDB.SQLiteConnection: sqlite3_key verification passed.
06-15 17:48:14.610 21999-21999/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 26] file is encrypted or is not a database
06-15 17:48:14.611 21999-21999/com.wlx.debug I/WCDB.SQLiteConnection: executeForString took 18ms - failed, sql="PRAGMA journal_mode", exception="file is encrypted or is not a database (code 26, errno 0): , while compiling: PRAGMA journal_mode"
06-15 17:48:14.611 21999-21999/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 26] file is encrypted or is not a database
06-15 17:48:14.612 21999-21999/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 26] file is encrypted or is not a database
06-15 17:48:14.612 21999-21999/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 26] file is encrypted or is not a database
06-15 17:48:14.612 21999-21999/com.wlx.debug V/WCDB.SQLiteConnection: Closing connection 0xb0562008
06-15 17:48:14.612 21999-21999/com.wlx.debug E/debug: main:CommonSQLHelper [OFFLINE]: CipherDB::onCorruption()
06-15 17:48:14.613 21999-21999/com.wlx.debug I/WCDB.SQLiteConnectionPool: Max connection pool size is 4.
06-15 17:48:14.613 21999-21999/com.wlx.debug I/WCDB: Initialize SQLite connection module 'MMFTS'...
06-15 17:48:14.613 21999-21999/com.wlx.debug I/WCDB.SQLiteConnection: Opened connection 0xb0562008 with label '/data/user/0/com.wlx.debug/databases/common_new'
06-15 17:48:14.613 21999-21999/com.wlx.debug I/WCDB.SQLiteConnection: sqlite3_key verification passed.
06-15 17:48:14.631 21999-21999/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 26] file is encrypted or is not a database
06-15 17:48:14.631 21999-21999/com.wlx.debug I/WCDB.SQLiteConnection: executeForString took 17ms - failed, sql="PRAGMA journal_mode", exception="file is encrypted or is not a database (code 26, errno 0): , while compiling: PRAGMA journal_mode"
06-15 17:48:14.632 21999-21999/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 26] file is encrypted or is not a database
06-15 17:48:14.632 21999-21999/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 26] file is encrypted or is not a database
06-15 17:48:14.632 21999-21999/com.wlx.debug W/WCDB.SQLite: [SQLite ErrCode: 26] file is encrypted or is not a database
06-15 17:48:14.632 21999-21999/com.wlx.debug V/WCDB.SQLiteConnection: Closing connection 0xb0562008
06-15 17:48:14.632 21999-21999/com.wlx.debug E/WCDB.SQLiteDatabase: Failed to open database '/data/user/0/com.wlx.debug/databases/common_new'.
06-15 17:48:14.633 21999-21999/com.wlx.debug E/debug: main:CommonSQLHelper [OFFLINE]: CipherDB::Open Fail. file is encrypted or is not a database (code 26, errno 0): , while compiling: PRAGMA journal_mode

关于复合主键

我看文档使用:
WCDB_PRIMARY(Message, localID)
设置主键,我如果想用复合主键,可以用如下的方法吗?
WCDB_PRIMARY(Message, localID)
WCDB_PRIMARY(Message, content)

describable.hpp 文件出错

通过cocoapods安装完成后,编译工程,describable.hpp 的#incloude 中提示:
‘list’ file not found!出错!

`WCDB_PROPERTY`, `WCDB_SYNTHESIZE` 修改建议

  • WCDB_PROPERTY 希望改成 WCDB_PROPERTY(className, propertyName), 在imp 中像WCDB_SYNTHESIZE增加WCDB_PROPERTY_HINT, 这样可以在指定WCDB_PROPERTY的时候有自动补全, 否则model中property多的时候写起来比较麻烦。

  • WCDB_SYNTHESIZE 希望增加到数据表字段的mapping, 比如可以自定义字段名称, 这么做是为了在老项目中使用WCDB的时候能做到兼容。比如可以改成 WCDB_SYNTHESIZE_CUSTOM(className, propertyName, customColumnName)。 另外希望默认columnName能把propertyName的驼峰命名方式映射为下划线分割, e.g.: propertyName => property_name.

请教个加密的问题

将密码的byte数组传进去加密了,如果我拿到数据库文件想在其他地方查看的话怎么看(如果工具让输入密码,我怎么根据设置的密码 生成 数据库实际使用的密码?),wcdb在底层是否对byte进一步运算生成了新密码?。

版本支持问题

ios 系统不支持 ios 7吗?后续会否支持?
我看文档没有说明android支持的版本,请问android支持的最低版本是多少?

Feature: ORM不依赖顺序

const WCTColumnBindingList &columnBindingList = binding->getColumnBindingList();

            auto columnNameIter = columnNameList.begin();
            auto columnBindingIter = columnBindingList.begin();
            while (columnBindingIter != columnBindingList.end()) {
                if (columnNameIter != columnNameList.end()) {
                    if (columnBindingIter->get()->columnName == *columnNameIter) {
                        ++columnBindingIter;
                    } else {
                        WCDB::Error::Warning([NSString stringWithFormat:@"Skip column named [%s] for table [%s]", columnNameIter->c_str(), tableName.UTF8String].UTF8String);
                    }
                    ++columnNameIter;
                } else {
                    //Add new column
                    if (!_core->exec(WCDB::StatementAlterTable()
                                         .alter(tableName.UTF8String)
                                         .addColumn(columnBindingIter->get()->getColumnDef()),
                                     error)) {
                        return NO;
                    }
                    ++columnBindingIter;
                }
            }
  1. 如果库里的列是1、2、3,然后类新增了字段4、5成为1、4、2、3、5。那么执行这个方法,只会把4插入进去。
  2. 如果库里的列是1、2、3、4,然后类的字段是1、4、2、3、5,在4匹配到的时候columnBindingIter和columnNameIter都+1,然后columnNameIter是end,而columnBindingIter是3,就变成了把3加入到表中。其实3是已经在里面的。

SQLiteDirectCursor性能提升问题

我们项目也有几个查询,会重复触发 windowcursor refill .
10000条数据,耗时在 14秒左右,使用 SQLiteDirectCursor 在11秒左右。

我们业务之前的做法是先查询一遍某个索引的范围,然后多线程查询再合并结果,耗时在 6秒左右,但写起来很复杂,而且不通用。

SQLiteDirectCursor 还有优化空间么。

无法通过pod 获取wcdb

无法通过pod search wcdb 搜索到 结果 提示 :[!] Unable to find a pod with name, author, summary, or description matching wcdb

自增的主键设置

WCDB_PRIMARY_ASC_AUTO_INCREMENT,自增的主键设置之后。
赋值操作不写这个字段。结果到后面insert第二个的时候,发现标记的字段并未自增。
insert操作报错:UNIQUE constraint failed

不知道是不是没有实现呢?
如果有实现的话,能否完善一下文档呢?谢谢了。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.