diff --git a/.gitignore b/.gitignore index 6ededb1..518fa84 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,11 @@ .gradle /local.properties /.idea +.idea/ .DS_Store /build /captures .externalNativeBuild app/release/app-release.apk +app/src/main/java/com/shunzhi/parent/DataBaseTestActivity.java +app/src/main/res/layout/activity_data_base_test.xml diff --git a/app/build.gradle b/app/build.gradle index 4be4291..a49cac9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -32,7 +32,7 @@ android { productFlavors { } } -greendao{ +greendao { schemaVersion 1//数据库版本升级 } dependencies { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0ed9333..4bacb24 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,53 +1,53 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.shunzhi.parent"> + package="com.shunzhi.parent"> <!-- 用于进行网络定位 --> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <!-- 用于访问GPS定位 --> - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> - <uses-permission android:name="android.permission.GET_TASKS" /> - <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> - <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> + <uses-permission android:name="android.permission.GET_TASKS"/> + <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <!-- Android 6.0版本可去除,用于选举信息(通道复用)的同步 --> - <uses-permission android:name="android.permission.WRITE_SETTINGS" /> + <uses-permission android:name="android.permission.WRITE_SETTINGS"/> <!-- 进行网络访问和网络状态监控相关的权限声明 --> - <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.INTERNET"/> <!-- 用于获取运营商信息,用于支持提供运营商信息相关的接口 --> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 --> - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <!-- 用于获取wifi的获取权限,wifi信息会用来进行网络定位 --> - <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> + <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <!-- 允许对sd卡进行读写操作 --> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!-- 用于申请调用A-GPS模块 --> - <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> + <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/> <!-- 网络库使用,当网络操作时需要确保事务完成不被杀掉 --> - <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission android:name="android.permission.WAKE_LOCK"/> <!-- 用于读取手机硬件信息等,用于机型过滤 --> - <uses-permission android:name="android.permission.READ_PHONE_STATE" /> + <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <!-- 选举使用,当应用有删除或者更新时需要重新选举,复用推送通道 --> - <uses-permission android:name="android.permission.BROADCAST_PACKAGE_CHANGED" /> - <uses-permission android:name="android.permission.BROADCAST_PACKAGE_REPLACED" /> - <uses-permission android:name="android.permission.RESTART_PACKAGES" /> + <uses-permission android:name="android.permission.BROADCAST_PACKAGE_CHANGED"/> + <uses-permission android:name="android.permission.BROADCAST_PACKAGE_REPLACED"/> + <uses-permission android:name="android.permission.RESTART_PACKAGES"/> <!-- 补偿通道小米PUSH使用,不用可去除 --> <!-- <uses-permission android:name="android.permission.GET_TASKS" /> --> <!-- 补偿通道GCM使用,不使用可去除 --> - <uses-permission android:name="android.permission.GET_ACCOUNTS" /> + <uses-permission android:name="android.permission.GET_ACCOUNTS"/> <!-- 允许监听启动完成事件 --> - <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> + <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <!-- 允许访问震动器 --> - <uses-permission android:name="android.permission.VIBRATE" /> + <uses-permission android:name="android.permission.VIBRATE"/> <!-- 允许task重排序 --> - <uses-permission android:name="android.permission.REORDER_TASKS" /> + <uses-permission android:name="android.permission.REORDER_TASKS"/> <!-- 用于申请获取蓝牙信息进行室内定位 --> - <uses-permission android:name="android.permission.BLUETOOTH" /> - <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + <uses-permission android:name="android.permission.BLUETOOTH"/> + <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <!-- 接收 SDK 消息广播权限, 第三方 APP 接入时,请将 com.netease.nim.demo 替换为自己的包名 --> - <uses-permission android:name="com.shunzhi.parent.permission.RECEIVE_MSG" /> - <uses-permission android:name="android.permission.CALL_PHONE" /> + <uses-permission android:name="com.shunzhi.parent.permission.RECEIVE_MSG"/> + <uses-permission android:name="android.permission.CALL_PHONE"/> <application android:name=".AppContext" @@ -59,7 +59,7 @@ android:theme="@style/Theme.AppCompat.Light.NoActionBar"> <!-- 高德地图服务 --> - <service android:name="com.amap.api.location.APSService" /> + <service android:name="com.amap.api.location.APSService"/> <!-- 高德地图密钥 --> <!-- <meta-data --> <!-- android:name="com.amap.api.v2.apikey" --> @@ -67,34 +67,34 @@ <!-- 家长慧测试APPkey --> - <!--<meta-data--> - <!--android:name="com.netease.nim.appKey"--> - <!--android:value="330158c080acdf4dc1092d6a74576c2c" />--> + <!-- <meta-data --> + <!-- android:name="com.netease.nim.appKey" --> + <!-- android:value="330158c080acdf4dc1092d6a74576c2c" /> --> <!-- 家长慧正式APPkey --> <meta-data android:name="com.netease.nim.appKey" - android:value="a1ff0bc08fa0d6f95b480d131e55584b" /> + android:value="a1ff0bc08fa0d6f95b480d131e55584b"/> <meta-data android:name="android.max_aspect" - android:value="2.1" /> + android:value="2.1"/> <!-- 声明云信后台服务 --> <service android:name="com.netease.nimlib.service.NimService" - android:process=":core" /> + android:process=":core"/> <!-- 运行后台辅助服务 --> <service android:name="com.netease.nimlib.service.NimService$Aux" - android:process=":core" /> + android:process=":core"/> <!-- 声明云信后台辅助服务 --> <service android:name="com.netease.nimlib.job.NIMJobService" android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE" - android:process=":core" /> + android:process=":core"/> <!-- 云信SDK的监视系统启动和网络变化的广播接收器,用户开机自启动以及网络变化时候重新登录 --> <receiver @@ -102,50 +102,48 @@ android:exported="false" android:process=":core"> <intent-filter> - <action android:name="android.intent.action.BOOT_COMPLETED" /> - <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> + <action android:name="android.intent.action.BOOT_COMPLETED"/> + <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> </receiver> <!-- 云信进程间通信receiver --> - <receiver android:name="com.netease.nimlib.service.ResponseReceiver" /> + <receiver android:name="com.netease.nimlib.service.ResponseReceiver"/> <!-- 云信进程间通信service --> - <service android:name="com.netease.nimlib.service.ResponseService" /> + <service android:name="com.netease.nimlib.service.ResponseService"/> <meta-data android:name="com.amap.api.v2.apikey" - android:value="1d130afb822d8a1019e6592cbaf10bcc" /> + android:value="1d130afb822d8a1019e6592cbaf10bcc"/> <activity android:name=".ui.activity.StartActivity" android:launchMode="singleInstance" android:windowSoftInputMode="adjustPan|stateAlwaysHidden"> <intent-filter> - <action android:name="android.intent.action.MAIN" /> + <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER" /> + <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> - <!--<activity--> - <!--android:name=".ui.MainActivity"--> - <!--android:screenOrientation="portrait"--> - <!--android:windowSoftInputMode="adjustPan|stateAlwaysHidden" />--> + <!-- <activity --> + <!-- android:name=".ui.MainActivity" --> + <!-- android:screenOrientation="portrait" --> + <!-- android:windowSoftInputMode="adjustPan|stateAlwaysHidden" /> --> <!-- <activity --> <!-- android:name=".ui.MainActivity" --> <!-- android:screenOrientation="portrait" --> <!-- android:windowSoftInputMode="adjustPan|stateAlwaysHidden" /> --> <activity android:name=".ui.activity.MyChildActivity" - android:screenOrientation="portrait" /> + android:screenOrientation="portrait"/> <activity android:name=".ui.activity.consult.ConsultOneLevelActivity" - android:windowSoftInputMode="adjustPan|stateAlwaysHidden" /> - + android:windowSoftInputMode="adjustPan|stateAlwaysHidden"/> <activity android:name=".ui.MainActivity" android:screenOrientation="portrait"/> - <activity android:name=".ui.activity.ChildDetialActivity" android:launchMode="singleInstance" @@ -154,27 +152,25 @@ android:name=".ui.activity.binding.CreateChildInfoActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" - android:windowSoftInputMode="adjustPan|stateHidden" /> + android:windowSoftInputMode="adjustPan|stateHidden"/> <activity android:name=".ui.activity.binding.SelectSchoolActivity" android:screenOrientation="portrait" - android:windowSoftInputMode="adjustPan|stateHidden" /> - + android:windowSoftInputMode="adjustPan|stateHidden"/> <activity android:name=".ui.activity.LoginAndRegistActivity" android:screenOrientation="portrait" - android:windowSoftInputMode="adjustPan|stateHidden" /> + android:windowSoftInputMode="adjustPan|stateHidden"/> <activity android:name=".ui.activity.PersonInfoActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" - android:windowSoftInputMode="adjustPan|stateHidden" /> + android:windowSoftInputMode="adjustPan|stateHidden"/> <activity android:name=".ui.activity.binding.CheckInfoActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" - android:windowSoftInputMode="adjustPan|stateHidden" /> - + android:windowSoftInputMode="adjustPan|stateHidden"/> <activity android:name=".ui.activity.binding.InviteCodeActivity" android:launchMode="singleInstance" @@ -183,20 +179,21 @@ android:name=".ui.activity.mywebview.WebViewActivity" android:launchMode="singleInstance" android:screenOrientation="portrait"/> - <activity android:name=".ui.activity.consult.ConsultTwoLevelActivity" android:launchMode="singleInstance" - android:windowSoftInputMode="adjustPan|stateAlwaysHidden" /> - + android:windowSoftInputMode="adjustPan|stateAlwaysHidden"/> <activity android:name=".ui.activity.orderdetail.OrderDetailActivity" - android:launchMode="singleInstance" /> + android:launchMode="singleInstance"/> <service android:name=".ui.service.BadgeIntentService" android:exported="false"> </service> + + <activity android:name=".DataBaseTestActivity"> + </activity> </application> </manifest> \ No newline at end of file diff --git a/app/src/main/assets/migrations/1.sql b/app/src/main/assets/migrations/1.sql new file mode 100644 index 0000000..7ee1ead --- /dev/null +++ b/app/src/main/assets/migrations/1.sql @@ -0,0 +1,2 @@ +ALTER table message add COLUMN test TEXT +UPDATE message SET test = 'sql默认' WHERE tes t= NULL--试过了,执行了,但是没有结果,并没有更新数据库内容 diff --git a/app/src/main/java/com/shunzhi/parent/AppContext.java b/app/src/main/java/com/shunzhi/parent/AppContext.java index f5a3b55..8da2400 100644 --- a/app/src/main/java/com/shunzhi/parent/AppContext.java +++ b/app/src/main/java/com/shunzhi/parent/AppContext.java @@ -21,10 +21,12 @@ import com.share.mvpsdk.helper.RetrofitCreateHelper; import com.shunzhi.parent.bean.message.DaoMaster; import com.shunzhi.parent.bean.message.DaoMaster.DevOpenHelper; import com.shunzhi.parent.bean.message.DaoSession; +import com.shunzhi.parent.dbhelper.GreenDaoDatabaseOpenHelper; import com.shunzhi.parent.manager.MessageManager; import com.shunzhi.parent.ui.MainActivity; import org.greenrobot.greendao.database.Database; +import org.greenrobot.greendao.database.DatabaseOpenHelper; /** * Created by Administrator on 2018/3/7 0007. @@ -79,7 +81,7 @@ public class AppContext extends GlobalApplication { // 经md5加密后取前n位做密码 // DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, ENCRYPTED ? "notes-db-encrypted" : "notes-db"); // Database db = ENCRYPTED ? helper.getEncryptedWritableDb("super-secret") : helper.getWritableDb(); - DevOpenHelper helper = new DevOpenHelper(this, "pw_messages"); + DatabaseOpenHelper helper = new GreenDaoDatabaseOpenHelper(this, "pw_messages"); Database db = helper.getWritableDb(); daoSession = new DaoMaster(db).newSession(); } diff --git a/app/src/main/java/com/shunzhi/parent/bean/message/PHMessage.java b/app/src/main/java/com/shunzhi/parent/bean/message/PHMessage.java index 5177f98..cd0e563 100644 --- a/app/src/main/java/com/shunzhi/parent/bean/message/PHMessage.java +++ b/app/src/main/java/com/shunzhi/parent/bean/message/PHMessage.java @@ -34,11 +34,11 @@ public class PHMessage { private Integer sendState;//消息发送的状态 1未发送(或者null,不建议使用null) 2发送中 3发送成功 4发送失败 private Integer sessionType; + @Generated(hash = 1935192071) public PHMessage(Long id, Date date, String messageId, String sessionId, - @NotNull String messageText, String exValue, String filePath, - String fileUrl, String messageType, Integer sendState, - Integer sessionType) { + @NotNull String messageText, String exValue, String filePath, String fileUrl, + String messageType, Integer sendState, Integer sessionType) { this.id = id; this.date = date; this.messageId = messageId; @@ -160,4 +160,5 @@ public class PHMessage { public void setSessionType(Integer sessionType) { this.sessionType = sessionType; } + } diff --git a/app/src/main/java/com/shunzhi/parent/dbhelper/DBUpdateHelper.java b/app/src/main/java/com/shunzhi/parent/dbhelper/DBUpdateHelper.java new file mode 100644 index 0000000..1a6b2d6 --- /dev/null +++ b/app/src/main/java/com/shunzhi/parent/dbhelper/DBUpdateHelper.java @@ -0,0 +1,137 @@ +package com.shunzhi.parent.dbhelper; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.support.annotation.StringDef; +import android.text.TextUtils; +import android.util.Log; + +import com.shunzhi.parent.dbhelper.utils.IOUtils; +import com.shunzhi.parent.dbhelper.utils.NaturalOrderComparator; +import com.shunzhi.parent.dbhelper.utils.SqlParser; + +import org.greenrobot.greendao.database.Database; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import timber.log.Timber; + +public class DBUpdateHelper { + + private Context context; + public final static String SQL_PARSER_LEGACY = "legacy"; + public final static String SQL_PARSER_DELIMITED = "delimited"; + + private final String mSqlParser; + + @StringDef({SQL_PARSER_DELIMITED, SQL_PARSER_LEGACY}) + @Retention(RetentionPolicy.SOURCE) + public @interface SQLParser { + + } + + public DBUpdateHelper(Context context, @SQLParser String sqlParser) { + this.context = context.getApplicationContext(); + mSqlParser = sqlParser; + } + + public boolean onUpdate(Database db, int oldVersion, int newVersion) { + return executeMigrations(db, oldVersion, newVersion); + } + + private boolean executeMigrations(Database db, int oldVersion, int newVersion) { + boolean migrationExecuted = false; + try { + final List<String> files = Arrays.asList(context.getAssets().list("migrations")); + Collections.sort(files, new NaturalOrderComparator()); + + db.beginTransaction(); + try { + for (String file : files) { + try { + final int version = Integer.valueOf(file.replace(".sql", "")); + + if (version > oldVersion && version <= newVersion) { + executeSqlScript(db, file); + migrationExecuted = true; + Timber.i("---==="+file + " executed succesfully."); + } + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + return migrationExecuted; + } + + private final static String MIGRATION_PATH = "migrations"; + + private void executeSqlScript(Database db, String file) { + + InputStream stream = null; + + try { + stream = context.getAssets().open(MIGRATION_PATH + "/" + file); + //因为我懒,不允许自定义解析方式 + //算了,还是加上吧 突然忘了类型限定怎么写了 就当练练手 + if (SQL_PARSER_DELIMITED.equalsIgnoreCase(mSqlParser)) { + executeDelimitedSqlScript(db, stream); + } else { + executeLegacySqlScript(db, stream); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(stream); + + } + } + + private void executeDelimitedSqlScript(Database db, InputStream stream) throws IOException { + + List<String> commands = SqlParser.parse(stream); + + for (String command : commands) { + db.execSQL(command); + } + } + + private void executeLegacySqlScript(Database db, InputStream stream) throws IOException { + + InputStreamReader reader = null; + BufferedReader buffer = null; + + try { + reader = new InputStreamReader(stream); + buffer = new BufferedReader(reader); + String line = null; + + while ((line = buffer.readLine()) != null) { + line = line.replace(";", "").trim(); + if (!TextUtils.isEmpty(line)) { + db.execSQL(line); + } + } + + } finally { + IOUtils.closeQuietly(buffer); + IOUtils.closeQuietly(reader); + + } + } +} diff --git a/app/src/main/java/com/shunzhi/parent/dbhelper/GreenDaoDatabaseOpenHelper.java b/app/src/main/java/com/shunzhi/parent/dbhelper/GreenDaoDatabaseOpenHelper.java new file mode 100644 index 0000000..47b964e --- /dev/null +++ b/app/src/main/java/com/shunzhi/parent/dbhelper/GreenDaoDatabaseOpenHelper.java @@ -0,0 +1,36 @@ +package com.shunzhi.parent.dbhelper; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; + +import com.shunzhi.parent.bean.message.DaoMaster; + +import org.greenrobot.greendao.database.Database; + +import timber.log.Timber; + +/** + * Created by 10501 on 2018/3/27. + */ + +public class GreenDaoDatabaseOpenHelper extends DaoMaster.OpenHelper { + private Context context; + + public GreenDaoDatabaseOpenHelper(Context context, String name) { + super(context, name); + this.context = context; + } + + public GreenDaoDatabaseOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) { + super(context, name, factory); + this.context = context; + } + + @Override + public void onUpgrade(Database db, int oldVersion, int newVersion) { + super.onUpgrade(db, oldVersion, newVersion); + DBUpdateHelper updateHelper = new DBUpdateHelper(context, DBUpdateHelper.SQL_PARSER_LEGACY); + boolean isSuccess = updateHelper.onUpdate(db, oldVersion, newVersion); + Timber.i("---===onUpgrade isSuccess : ", isSuccess); + } +} diff --git a/app/src/main/java/com/shunzhi/parent/dbhelper/utils/IOUtils.java b/app/src/main/java/com/shunzhi/parent/dbhelper/utils/IOUtils.java new file mode 100644 index 0000000..62359ed --- /dev/null +++ b/app/src/main/java/com/shunzhi/parent/dbhelper/utils/IOUtils.java @@ -0,0 +1,35 @@ +package com.shunzhi.parent.dbhelper.utils; + +import android.database.Cursor; +import android.util.Log; + +import java.io.Closeable; +import java.io.IOException; + +/** + * Created by 10501 on 2018/3/26. + */ + +public class IOUtils { + public static void closeQuietly(Closeable closeable) { + if(closeable != null) { + try { + closeable.close(); + } catch (IOException var2) { + var2.printStackTrace(); + } + + } + } + + public static void closeQuietly(Cursor cursor) { + if(cursor != null) { + try { + cursor.close(); + } catch (Exception var2) { + var2.printStackTrace(); + } + + } + } +} diff --git a/app/src/main/java/com/shunzhi/parent/dbhelper/utils/NaturalOrderComparator.java b/app/src/main/java/com/shunzhi/parent/dbhelper/utils/NaturalOrderComparator.java new file mode 100644 index 0000000..7981af4 --- /dev/null +++ b/app/src/main/java/com/shunzhi/parent/dbhelper/utils/NaturalOrderComparator.java @@ -0,0 +1,117 @@ +package com.shunzhi.parent.dbhelper.utils; + +import java.util.Comparator; + +public class NaturalOrderComparator implements Comparator<Object> { + int compareRight(String a, String b) { + int bias = 0; + int ia = 0; + int ib = 0; + + // The longest run of digits wins. That aside, the greatest + // value wins, but we can't know that it will until we've scanned + // both numbers to know that they have the same magnitude, so we + // remember it in BIAS. + for (;; ia++, ib++) { + char ca = charAt(a, ia); + char cb = charAt(b, ib); + + if (!Character.isDigit(ca) && !Character.isDigit(cb)) { + return bias; + } + else if (!Character.isDigit(ca)) { + return -1; + } + else if (!Character.isDigit(cb)) { + return +1; + } + else if (ca < cb) { + if (bias == 0) { + bias = -1; + } + } + else if (ca > cb) { + if (bias == 0) + bias = +1; + } + else if (ca == 0 && cb == 0) { + return bias; + } + } + } + + public int compare(Object o1, Object o2) { + String a = o1.toString(); + String b = o2.toString(); + + int ia = 0, ib = 0; + int nza = 0, nzb = 0; + char ca, cb; + int result; + + while (true) { + // only count the number of zeroes leading the last number compared + nza = nzb = 0; + + ca = charAt(a, ia); + cb = charAt(b, ib); + + // skip over leading spaces or zeros + while (Character.isSpaceChar(ca) || ca == '0') { + if (ca == '0') { + nza++; + } + else { + // only count consecutive zeroes + nza = 0; + } + + ca = charAt(a, ++ia); + } + + while (Character.isSpaceChar(cb) || cb == '0') { + if (cb == '0') { + nzb++; + } + else { + // only count consecutive zeroes + nzb = 0; + } + + cb = charAt(b, ++ib); + } + + // process run of digits + if (Character.isDigit(ca) && Character.isDigit(cb)) { + if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0) { + return result; + } + } + + if (ca == 0 && cb == 0) { + // The strings compare the same. Perhaps the caller + // will want to call strcmp to break the tie. + return nza - nzb; + } + + if (ca < cb) { + return -1; + } + else if (ca > cb) { + return +1; + } + + ++ia; + ++ib; + } + } + + static char charAt(String s, int i) { + if (i >= s.length()) { + return 0; + } + else { + return s.charAt(i); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/shunzhi/parent/dbhelper/utils/SqlParser.java b/app/src/main/java/com/shunzhi/parent/dbhelper/utils/SqlParser.java new file mode 100644 index 0000000..80e3093 --- /dev/null +++ b/app/src/main/java/com/shunzhi/parent/dbhelper/utils/SqlParser.java @@ -0,0 +1,93 @@ +package com.shunzhi.parent.dbhelper.utils; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + + +public class SqlParser { + + public final static int STATE_NONE = 0; + public final static int STATE_STRING = 1; + public final static int STATE_COMMENT = 2; + public final static int STATE_COMMENT_BLOCK = 3; + + public static List<String> parse(final InputStream stream) throws IOException { + + final BufferedInputStream buffer = new BufferedInputStream(stream); + final List<String> commands = new ArrayList<String>(); + final StringBuffer sb = new StringBuffer(); + + try { + final Tokenizer tokenizer = new Tokenizer(buffer); + int state = STATE_NONE; + + while (tokenizer.hasNext()) { + final char c = (char) tokenizer.next(); + + if (state == STATE_COMMENT_BLOCK) { + if (tokenizer.skip("*/")) { + state = STATE_NONE; + } + continue; + + } else if (state == STATE_COMMENT) { + if (isNewLine(c)) { + state = STATE_NONE; + } + continue; + + } else if (state == STATE_NONE && tokenizer.skip("/*")) { + state = STATE_COMMENT_BLOCK; + continue; + + } else if (state == STATE_NONE && tokenizer.skip("--")) { + state = STATE_COMMENT; + continue; + + } else if (state == STATE_NONE && c == ';') { + final String command = sb.toString().trim(); + commands.add(command); + sb.setLength(0); + continue; + + } else if (state == STATE_NONE && c == '\'') { + state = STATE_STRING; + + } else if (state == STATE_STRING && c == '\'') { + state = STATE_NONE; + + } + + if (state == STATE_NONE || state == STATE_STRING) { + if (state == STATE_NONE && isWhitespace(c)) { + if (sb.length() > 0 && sb.charAt(sb.length() - 1) != ' ') { + sb.append(' '); + } + } else { + sb.append(c); + } + } + } + + } finally { + IOUtils.closeQuietly(buffer); + } + + if (sb.length() > 0) { + commands.add(sb.toString().trim()); + } + + return commands; + } + + private static boolean isNewLine(final char c) { + return c == '\r' || c == '\n'; + } + + private static boolean isWhitespace(final char c) { + return c == '\r' || c == '\n' || c == '\t' || c == ' '; + } +} diff --git a/app/src/main/java/com/shunzhi/parent/dbhelper/utils/Tokenizer.java b/app/src/main/java/com/shunzhi/parent/dbhelper/utils/Tokenizer.java new file mode 100644 index 0000000..6b1eba3 --- /dev/null +++ b/app/src/main/java/com/shunzhi/parent/dbhelper/utils/Tokenizer.java @@ -0,0 +1,59 @@ +package com.shunzhi.parent.dbhelper.utils; + +import java.io.IOException; +import java.io.InputStream; + + +public class Tokenizer { + + private final InputStream mStream; + + private boolean mIsNext; + private int mCurrent; + + public Tokenizer(final InputStream in) { + this.mStream = in; + } + + public boolean hasNext() throws IOException { + + if (!this.mIsNext) { + this.mIsNext = true; + this.mCurrent = this.mStream.read(); + } + return this.mCurrent != -1; + } + + public int next() throws IOException { + + if (!this.mIsNext) { + this.mCurrent = this.mStream.read(); + } + this.mIsNext = false; + return this.mCurrent; + } + + public boolean skip(final String s) throws IOException { + + if (s == null || s.length() == 0) { + return false; + } + + if (s.charAt(0) != this.mCurrent) { + return false; + } + + final int len = s.length(); + this.mStream.mark(len - 1); + + for (int n = 1; n < len; n++) { + final int value = this.mStream.read(); + + if (value != s.charAt(n)) { + this.mStream.reset(); + return false; + } + } + return true; + } +} diff --git a/app/src/main/java/com/shunzhi/parent/ui/fragment/MineFragment.java b/app/src/main/java/com/shunzhi/parent/ui/fragment/MineFragment.java index 6afad89..2819f49 100644 --- a/app/src/main/java/com/shunzhi/parent/ui/fragment/MineFragment.java +++ b/app/src/main/java/com/shunzhi/parent/ui/fragment/MineFragment.java @@ -18,6 +18,8 @@ import com.share.mvpsdk.base.fragment.BaseMVPCompatFragment; import com.share.mvpsdk.utils.CacheUtils; import com.shunzhi.parent.AppConfig; import com.shunzhi.parent.AppContext; +import com.shunzhi.parent.BuildConfig; +import com.shunzhi.parent.DataBaseTestActivity; import com.shunzhi.parent.R; import com.shunzhi.parent.contract.loginandregister.LoginAndRegisterContract; import com.shunzhi.parent.contract.mine.MineContract; @@ -73,15 +75,19 @@ public class MineFragment extends BaseMVPCompatFragment<LoginAndRegisterContract tvExit.setOnClickListener(this); binding_state = view.findViewById(R.id.binding_state); layout_afterLogin.setVisibility(View.GONE); - + if (BuildConfig.DEBUG) { + View enter = view.findViewById(R.id.testEnter); + enter.setVisibility(View.VISIBLE); + enter.setOnClickListener(this); + } else view.findViewById(R.id.testEnter).setVisibility(View.GONE); } private void setPersonInfo() { - String useName=AppConfig.getAppConfig(getContext()).get(AppConfig.USER_NAME); - if (!TextUtils.isEmpty(useName))AppConfig.ISLOGIN=true; - else AppConfig.ISLOGIN=false; + String useName = AppConfig.getAppConfig(getContext()).get(AppConfig.USER_NAME); + if (!TextUtils.isEmpty(useName)) AppConfig.ISLOGIN = true; + else AppConfig.ISLOGIN = false; if (TextUtils.isEmpty(AppConfig.getAppConfig(getContext()).get(AppConfig.ISBINDING))) { binding_state.setText(""); @@ -148,7 +154,9 @@ public class MineFragment extends BaseMVPCompatFragment<LoginAndRegisterContract case R.id.layout_feedback: WebViewActivity.getInstance(getActivity(), AppConfig.BASE_URL_ORDER + "FeedBack.aspx?userid=" + AppConfig.getAppConfig(AppContext.getInstance()).get(AppConfig.USER_ID), -1); - + break; + case R.id.testEnter: + DataBaseTestActivity.start(this); break; default: break; diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml index bca7776..8a1c82d 100644 --- a/app/src/main/res/layout/fragment_mine.xml +++ b/app/src/main/res/layout/fragment_mine.xml @@ -339,6 +339,20 @@ android:textColor="@color/white" android:textSize="@dimen/size_dp_16" /> + <TextView + android:id="@+id/testEnter" + android:layout_width="match_parent" + android:layout_height="?android:actionBarSize" + android:layout_gravity="center_vertical" + android:gravity="center" + android:layout_weight="1" + android:layout_marginTop="@dimen/size_dp_15" + android:layout_marginBottom="@dimen/size_dp_15" + android:background="@drawable/shape_xueqing_radius8" + android:text="测试入口" + android:textColor="@color/white" + android:textSize="@dimen/size_dp_16" /> + </LinearLayout> </ScrollView> -- libgit2 0.21.0