null で更新

    public void updateScore(int id, ExeMode method, int? score) {
        string item = CommonDao.GetScoreItemName(method);
        // How to string format
        string sql = $"UPDATE LessonTable SET {item} ={(score == null ? "null" : score.ToString())} WHERE ID ={id}";

        dbManager.Execute(sql);
    }

項目を動的に変えてデータを取得

void Start()
{
	dbManager = this.GetComponentInParent();
}

public int GetScore(int id, ExeMode method)
{
	string item = CommonDao.GetScoreItemName(method);
	string sql = $"SELECT {item} FROM LessonTable WHERE ID=?";

	SimpleDataTable lists = dbManager.QueryGeneric(sql, id);

	if(lists.rows.Count ==0 ) {
		return 0;
	}
	return int.Parse(lists.rows[0][0].ToString());
}

Swift SharkORM を使用するには?

新規プロジェクトを XCode で作成して、一旦閉じる。(SharkORMTest)

ターミンナルより SharkORMTest に移動

pod init

Profile に 以下の様に編集

# Uncomment the next line to define a global platform for your project
platform :ios, '11.0'

target 'SharkOrmTest' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  #use_frameworks!
  pod 'SharkORM'

  # Pods for SharkOrmTest

  target 'SharkOrmTestTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'SharkOrmTestUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end

以下のコマンドを実行
pod install

xcode にて SharkOrmTest.xcodeproj ではなく SharkOrmTest.xcworkspace を開く

SharkHeader.h ブリッジヘッダーファイルを作成

#ifndef SharkHeader_h
#define SharkHeader_h

#include <SharkORM/SharkORM.h>

#endif /* SharkHeader_h */

build settings
-> objective-c Bridging Heatter に以下を追加

$(SRCROOT)/$(PRODUCT)/SharkHeader.h

上記を忘れると以下のエラーが出ます。

Use of undeclared type 'SRKDelegate'
Use of undeclared type 'SRKObject'

テーブルに対応するクラスを作成

import Foundation
import SharkORM

class Sentence: SRKObject {
    @objc dynamic var _id : NSNumber?
    @objc dynamic var categoryId : NSNumber?
    @objc dynamic var english : String?
    @objc dynamic var japanese : String?
    @objc dynamic var okCount : NSNumber?
    @objc dynamic var ngCount : NSNumber?
    @objc dynamic var average : NSNumber?
}

以下、追加

import SharkORM

class AppDelegate: UIResponder, UIApplicationDelegate, SRKDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        SharkORM.setDelegate(self)
        SharkORM.openDatabaseNamed("myDatabase")
        initDb()
        return true
    }

    func initDb() {

        insertData(english:"this is a pen.")
        insertData(english:"this is an apple.")
        insertData(english:"can you speack japanese.")

        var results = Sentence.query().fetch()
        print(String(format: "count:%d", (results?.count)!))
        for sentence in results! {
            let s = sentence as! Sentence
            print((sentence as AnyObject).english)
        }

    }

    func insertData( english: String ) {
        var a = Sentence()
        a.english = english
        a.commit()
    }

色々とハマタ

2017年 Android の ORM は、DbFlow に決まったと確信しました。

あまりにも導入しやすいく、あまりにも移行しやすく、あまりにもコードが簡単になる。
感動しました。

自分にとっての ORM はスピードは二の次です。
簡単に管理、コーディング出来ることが最優先です。

Create table やら、OpenDatabase やら、 Open Cursor はもやは不要です。
項目定義もクラス定義することで完了です。
感動です。

なので、使い方を紹介します。
詳しくは
https://www.gitbook.com/book/agrosner/dbflow/details

project gradle

allProjects {
    repositories {
        // required to find the project's artifacts
        maven { url "https://www.jitpack.io" }
    }
}

app gradle

def dbflow_version = "4.0.5"
dependencies {
    apt "com.github.Raizlabs.DBFlow:dbflow-processor:${dbflow_version}"
    compile "com.github.Raizlabs.DBFlow:dbflow-core:${dbflow_version}"
    compile "com.github.Raizlabs.DBFlow:dbflow:${dbflow_version}"
}

db class

@Database(name = HatuonDb.NAME, version = HatuonDb.VERSION, generatedClassSeparator = "_")
public class HatuonDb {
    public static final String NAME = "pronunce";
    public static final int VERSION = 1;

}

table class

@Table(database = HatuonDb.class, name="T_WORD")
public class Word extends BaseModel {
    @PrimaryKey(autoincrement = true)
     public long id;

    @Column
    public String word;
    @Column
    public String type;
    @Column
    public String kigou;
    @Column
    public int ngCount;
    @Column
    public int okCount;
    @Column
    public int average;
    @Column
    public String japanese;

    @Column
    public long createdTimeMillis;
}

application class

必要なのは、FlowManager.init(this); のみ
他のコードは、SD Card に DB を保存する為にコードです。

public class MyApplication extends android.app.Application {

@Override
public void onCreate() {
    super.onCreate();
    // PronunceDbExtract();
    FlowManager.init(this);
}

@Override
public SQLiteDatabase openOrCreateDatabase(String name,
   int mode, SQLiteDatabase.CursorFactory factory) {
    return super.openOrCreateDatabase(getDatabasePath(name).getAbsolutePath(), mode, factory);
}

@Override
public SQLiteDatabase openOrCreateDatabase(String name,
    int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
    return super.openOrCreateDatabase(getDatabasePath(name).getAbsolutePath(), mode, factory, errorHandler);
}

@Override
public boolean deleteDatabase(String name) {
    return super.deleteDatabase(getDatabasePath(name).getAbsolutePath());
}

@Override
public File getDatabasePath(String name) {
    File file = new File(Environment.getExternalStorageDirectory(), name);
    return file;
}

/*
protected void MyDbExtract() {
    String outFile = Environment.getExternalStorageDirectory() +"/" + HatuonDb.NAME + ".db";
    if(!new File(outFile).exists()) {
        FileUtils.copyAssetsFile(getApplicationContext(), "db/hatuon.db", outFile);
    }
}
*/
}

使い方

// 項目名は、 Table名_item で自動生成してくれる
// select * from word where okCOunt = 0 and ngCount = 0
List list = SQLite.select().from(Word.class).where(Word_Table.okCount.eq(0)).and(Word_Table.ngCount.eq(0)).queryList();

// update word set ngCount = ngcount + 1, average = 50 where id = XXX
Word word = list.get(0);
word.ngCount = word.ngCount + 1;
word.average = 50;
word.save;

// count
int count = SQLite.selectCountOf().from(Word.class).count();

// in
List<String> wordList = Arrays.asList(sentence.split(" "));

List<HatuonKigou> words = new Select().from(HatuonKigou.class)
                                  .where(HatuonKigou_Table.word.in(wordList))
                                  .queryList();
Log2.e( new Select().from(HatuonKigou.class)
                     .where(HatuonKigou_Table.word.in(wordList))
                     .getQuery()
                     .toString());

// delete
String category = "sentence_5";
SQLite.delete().from(Sentence.class).where(Sentence_Table.category.eq(category)).async().execute();
     
// sort + count 
Sentence list = SQLite.select().from(Sentence.class)
                .where()
                .and(Sentence_Table.isWord.eq(isWord))
                .and(Sentence_Table.category.eq(category))
                .orderBy(Sentence_Table.average, true)
                .limit(30)
                .queryList();


詳しくは、こちら

ORM は、色々ありますが、すでに、開発が終了していたり、使うときにさらに別クラス宣言が必要だったり、
導入が面倒だったり、自動生成されるクラスが生成されなかったり、なんか良いのないのかと一生懸命
さがしました。realm も試しましたが、スキーマを静的に変えようとおもってもツールが見つから
なかったりと、そんななかで DbFlow を見つけました。
SQLite なら静的にスキーマを変えるツールもたくさんあるし、楽ちんです。

コードは、半減します。
ぜひお試しあれ

ただ、最大の欠点は、iOS 版が無いんですよね

android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
上のエラーがでた、でもカーソルの項目は1以上

結論、レコードが0件だった!
項目にアクセスする前に件数確認

c = db.query("T_IMAGE_STORY",
    new String[] { "ID" },
    "CATEGORY_ID = ? AND POS = ?",
    new String[] { String.valueOf(categoryId), String.valueOf(pos) }, 
    null, 
    null, "ID");

if(( c != null ) && c.getCount() > 0 ) {
    c.moveToFirst();
    id = c.getSting( 0 );

adb shell 実行時、漢字が文字化け

DOSプロンプト起動時、フォントをMSゴシック
コマンドラインから CHCP 65001 を実行

sqlite3 dbname.db

sqlite3 database.db
pragma table_info( TABLE_NAME ) 


Cursor ti = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);
if (ti.moveToFirst()) {
	do {
		System.out.println("col: " + ti.getString(1));
	} while (ti.moveToNext());
}
© 2024 Falco Tech Blog Suffusion theme by Sayontan Sinha