読者です 読者をやめる 読者になる 読者になる

FolderBrowserDialogのRootFolderをDesktopDirectoryにすると、Windows10では死ぬ

.NETでフォルダ参照ダイアログにFolderBrowserDialogを使ってるのだが、プロパティのRootFolderにDesktopDirectoryを指定すると、Windows10ではフォルダ参照が機能しなくなる。

サンプルのフォルダ参照ダイアログ表示処理

RootFolderを指定しないFolderBrowserDialogの例として、以下のようなプログラムを用意した。

FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.Description = "素のFolderBrowserDialog";
DialogResult result = dialog.ShowDialog();

RootFolderを指定するFolderBrowserDialogの例として、以下のようなプログラムを用意した。

FolderBrowserDialog dialog = new FolderBrowserDialog();
dialog.RootFolder = Environment.SpecialFolder.DesktopDirectory;
dialog.Description = "RootFolderをDesktopDirectoryにしたFolderBrowserDialog";
DialogResult result = dialog.ShowDialog();

Windows7での動作

上のサンプルをWindows7で動かしてみる。
まずはRootFolderを指定しないFolderBrowserDialog。
f:id:nave_kazu:20160914175801p:plain

続いてRootFolderを指定するFolderBrowserDialog。
f:id:nave_kazu:20160914175806p:plain

見た目はまったく同じ。

Windows10での動作

これがWindows10だと、こうなる。
まずはRootFolderを指定しないFolderBrowserDialog。
f:id:nave_kazu:20160914175811p:plain

続いてRootFolderを指定するFolderBrowserDialog。
f:id:nave_kazu:20160914175814p:plain

すっからかんになった。
デスクトップの下はデスクトップにあるフォルダしか表示されなくなる。

回避策

そもそも、RootFolderの指定にDesktopDirectoryを指定するからこうなるのであって、デスクトップを初期表示したければ規定値のDesktop(DesktopDirectoryではなくDesktop)を使えということ。
MSDNによるとDesktopDirectoryは「デスクトップ上のファイル オブジェクトを物理的に格納するために使用されるディレクトリ。」となっている。
Desktopは「物理的なファイル システム上の場所ではない論理的なデスクトップ。」となっている。

いままでは物理的には実在しない「コンピュータ」とか「コントロールパネル」を表示していたが、Windows10からは厳密に実在するフォルダしか表示しないという動きに変わったということ。
Windows8.1は、Windows7と同じ動きをしていた。

Windows10対応のひとつだね。

Linux (CentOS 7) で GitBucket を動かす

開発サーバーにGitBucketを入れたので、その手順をメモする。
入れたものは下記のとおり。

製品 バージョン 参照先
JDK 8u101-linux-x64 Java SE Development Kit 8 - Downloads
Tomcat 8.5.5 Apache Tomcat® - Apache Tomcat 8 Software Downloads
GitBucket 4.4 Release 4.4 · gitbucket/gitbucket · GitHub

それぞれの手順を順に記す。

JDK

TomcatとGitBucketを動かすためにJDKを入れる。
Oracleのダウンロードページから、現在最新版の8u101をダウンロードする。
手元のLinuxは64bitなので、linux-x64を。
RPMの方が楽なのでjdk-8u101-linux-x64.rpmをダウンロード。

JDKのインストール

RPMファイルがあるフォルダで下記コマンドを実行

yum localinstall --nogpgcheck jdk-8u101-linux-x64.rpm

インストール出来たか確認する。

# java -version
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

環境変数を設定

/etc/profileに環境変数 JAVA_HOME を設定する。
/etc/profile をエディタ開いて、下記を追加。

export JAVA_HOME=/usr/java/default

Tomcat

GitBucketは組み込みのウェブサーバーが入っているのでそちらで動かしても良いが、今回はTomcatの上で動かす。

ユーザー作成

まずはTomcatを動かすためのユーザー tomcat を作る。

useradd -s /sbin/nologin tomcat

Tomcatのインストール

ダウンロードサイトからTomcatのtar.gzファイルをダウンロードし、適当なフォルダに展開する。

tar xvzf apache-tomcat-8.5.5.tar.gz

展開したファイルを /usr/local に移動する。

mv apache-tomcat-8.5.5 /usr/local

所有者を先ほど作成したtomcatに変更する。

cd /usr/local
chown -R tomcat:tomcat apache-tomcat-8.5.5

Tomcatシンボリックリンクを作成する。

ln -s apache-tomcat-8.5.5 tomcat

環境変数を設定

/etc/profileに環境変数 CATALINA_HOME を設定する。
/etc/profile をエディタ開いて、下記を追加。

export CATALINA_HOME=/usr/local/tomcat

Tomcatをデーモンとして動かす

サーバーなのでサーバー起動時に自動で立ち上がって欲しいからデーモンとして動かす。
Tomcatには jsvc というデーモン化ツールがあるので、それをセットアップして使う。

まずはTomcatのインストールフォルダのbinに移動。

cd /usr/local/tomcat/bin

jsvcのアーカイブを展開。

tar xvzf commons-daemon-native.tar.gz

展開後のフォルダに移動。

cd  commons-daemon-1.0.15-native-src/unix

Makeファイルを生成。

./configure

makeを実行。

make

出来たjsvcをコピー。

cp jsvc ../..

ここまででデーモン起動用のシェルが作成されるので、試しに起動してみる。

cd /usr/local/tomcat/bin
./daemon.sh start

ブラウザで http://localhost:8080/ にアクセスする。
リモートの環境ならlocalhostではなく対象のIPアドレスなりを入力すること。
もし実行環境のファイアーウォールが原因でアクセスできない場合は8080ポートを空ける等、適宜対応を。

firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --reload

起動用のスクリプトを /usr/lib/systemd/system/tomcat.service に作成する。
/usr/lib/systemd/system/tomcat.service をエディタで新規作成する。
内容は下記のとおり。

[Unit]
Description=Apache Tomcat Web Application Container
After=network.target

[Service]
Type=forking
PIDFile=/var/run/tomcat.pid
Environment=CATALINA_PID=/var/run/tomcat.pid
Environment=JAVA_HOME=/usr/java/default
Environment=CATALINA_HOME=/usr/local/tomcat
Environment=CATALINA_BASE=/usr/local/tomcat
Environment=CATALINA_OPTS=

ExecStart=/usr/local/tomcat/bin/jsvc \
            -Dcatalina.home=${CATALINA_HOME} \
            -Dcatalina.base=${CATALINA_BASE} \
            -cp ${CATALINA_HOME}/bin/commons-daemon.jar:${CATALINA_HOME}/bin/bootstrap.jar:${CATALINA_HOME}/bin/tomcat-juli.jar \
            -user tomcat \
            -java-home ${JAVA_HOME} \
            -pidfile /var/run/tomcat.pid \
            -errfile SYSLOG \
            -outfile SYSLOG \
            $CATALINA_OPTS \
            org.apache.catalina.startup.Bootstrap

ExecStop=/usr/local/tomcat/jsvc \
            -pidfile /var/run/tomcat.pid \
            -stop \
            org.apache.catalina.startup.Bootstrap

[Install]
WantedBy=multi-user.target
	||<

サービス登録をする。
>|sh|
systemctl enable tomcat.service

GitBucket

最後にGitBucketを入れる。
GitBucketのWARファイルをダウンロードし、Tomcat の webapps フォルダにコピーする。

cp gitbucket.war /usr/local/tomcat/webapps

ホットデプロイされていないようなら Tomcat を再起動する。

systemctl restart tomcat

ブラウザで http://localhost:8080/gitbucket/ にアクセスする。
GitBucketのトップ画面が出てきたらOK。

Oracle Databaseのインストーラの文字化け対策

Linux版のOracle Database 11g R2のインストールで文字化けに苦しんだので対策方法をメモ。

文字化けの根本原因はOracle Databaseに付属のJREインストーラを起動するからであって、付属のJRE以外を使うというのが基本的な回避方法。

文字化けしたのは下記の3つ。
・OUI (Oracle Universal Installer) → Oracle Database本体のインストーラ
・DBCA (Database Configuration Assistant) → データベース作成ツール
・NETCA (Net Configuration Assistant) → リスナ作成ツール

Open JDKでもOracleJDKでも良いので付属のJRE以外が必要なので別途ダウンロードしてインストール後、それぞれ文字化けするツールを別途インストールしたJDKに付いてくるJREを見るように設定変更する。

JDKのインストール

Open JDKでもOracleJDKでも良いのでインストールする。
今回はOracleJDKRPM形式でダウンロードしてインストールした。
ダウンロードしたファイルは jdk-8u91-linux-x64.rpm で、それを下記のrpmコマンドでインストールする。

rpm -ivh jdk-8u91-linux-x64.rpm

すると /usr/java/jdk1.8.0_91 にインストールされるので、ここにある jre ディレクトリのJREを以降では使うようにする。

OUI (Oracle Universal Installer) の起動

OUIの起動は runInstaller にパラメータで JRE の場所を指定する。

./runInstaller -jreLoc /usr/java/jdk1.8.0_91/jre/

DBCA (Database Configuration Assistant) の起動

DBCAの起動は、起動シェルを書き換えてJREの場所を指定する。
起動シェルは $ORACLE_HOME/bin/dbca 。

vi $ORACLE_HOME/bin/dbca

"JRE_DIR"で検索すると以下の行がある。

JRE_DIR=/opt/app/oracle/product/11.2.0/db_1/jdk/jre

それを、インストールしたJDKJREを見るように変更する。

#JRE_DIR=/opt/app/oracle/product/11.2.0/db_1/jdk/jre
JRE_DIR=/usr/java/jdk1.8.0_91/jre

あとは通常通りに dbca を起動すればOK。

NETCA (Net Configuration Assistant) の起動

NETCAもDBCAと方法は同じ。
起動シェルを書き換えてJREの場所を指定する。
起動シェルは $ORACLE_HOME/bin/netca 。

vi $ORACLE_HOME/bin/netca

"JRE_DIR"で検索すると以下の行がある。

JRE_DIR=/opt/app/oracle/product/11.2.0/db_1/jdk/jre

それを、インストールしたJDKJREを見るように変更する。

#JRE_DIR=/opt/app/oracle/product/11.2.0/db_1/jdk/jre
JRE_DIR=/usr/java/jdk1.8.0_91/jre

あとは通常通りに netca を起動すればOK。

マスターテーブルとenum

昨日、三浦カズヒトさんと Twitter でやりとりさせてもらった。

あまり深く考えずにリプライしてしまい中途半端にしか答えられなかったので、ツイッターの文字数制限に縛られない場所で自分の考えをまとめてみた。

問題

データベースのマスターテーブルにキーと名称のペアがあったとして、それと同じペアをenumや定数でプログラムに持つのが、果たして良いことなのか。
どうせマスターにペアを追加するときはそれに対応するプログラムをデプロイするし、マスターとプログラムの両方を手直しするならマスターなんて持たずにプログラムだけで対応すれば良いのではないだろうか。
マスターに名称を持つ価値は、せいぜい急な名称変更に対応出来る程度なのではないか。

マスターとenumの両方を持つ理由

マスターには値の名称を持ち、enumではそのマスターに応じた処理を分岐させるための定数とするよう、両方を持つのだと思う。
例えば、マスターに以下のようなものがあったとする。

種別番号 種別名
0
1
2

それに応じたenumを用意すると、こうなる。

public enum Kind {
    DAI,    // 種別番号 0「大」 を表す
    CYU,    // 種別番号 1「中」 を表す
    SYO     // 種別番号 2「小」 を表す
}

で、種別ごとに何らかの処理を実装すると、こうなる。

    public void someProcess(Kind kind) {
        switch (kind) {
            case DAI:
                // 種別番号 0「大」 の時の処理
                break;

            case CYU:
                // 種別番号 1「中」 の時の処理
                break;

            case SYO:
                // 種別番号 2「小」 の時の処理
                break;
        }
    }

このような実装をしていたら、マスターに種別を増やした場合にそれに応じたenumを増やして、更にそのenumを使っている箇所に処理を追加しないとならない。
例えば「極小」を追加したらマスターは下記のようになる。

種別番号 種別名
0
1
2
3 極小

それに応じてenumの「GOKUSYO」も増やす。

public enum Kind {
    DAI,    // 種別番号 0「大」 を表す
    CYU,    // 種別番号 1「中」 を表す
    SYO,    // 種別番号 2「小」 を表す
    GOKUSYO // 種別番号 3「極小」 を表す
}

さらに「case GOKUSYO」の処理を増やす。

    public void someProcess(Kind kind) {
        switch (kind) {
            case DAI:
                // 種別番号 0「大」 の時の処理
                break;

            case CYU:
                // 種別番号 1「中」 の時の処理
                break;

            case SYO:
                // 種別番号 2「小」 の時の処理
                break;

            case GOKUSYO:
                // 種別番号 3「極小」 の時の処理
                break;
        }
    }

種別が変更になるたびにマスターとenumと処理を増やすのは、正直しんどい。
だったらマスターを捨ててenumだけで良いのでは?というのも分かる。

マスターだけにする

種別に応じた処理をマスターに基いてやるようにすれば、enumも処理も不要になるケースがある。
例えばマスターに処理をするのに必要なパラメータを登録するというやり方。

種別番号 種別名 パラーメータ1 パラーメータ2
0 789 JKL
1 456 GHI
2 123 DEF
3 極小 0 ABC

処理はこのようになる。

    public void someProcess(int kind) {
        int param1 = getParam1(kind);    // マスターから種別番号に応じたパラメータ1を取得
        String param2 = getParam2(kind); // マスターから種別番号に応じたパラメータ2を取得

        // param1とparam2を基に処理する

    }

処理は同じだが種別によってパラメータが違うという場合なら、これで十分対応が可能と思う。
これならマスターだけをメンテすれば万事OK。

マスターもenumも持たない

マスターがキーと値のペアだけだったら、マスターを持たないという選択もありだと思う。
かと言って、enumと処理がバラバラだとそれはそれでしんどいので、もうマスターもenumも持たないようにしたい。

マスターをなくしたので、種別に応じた種別名を取得する仕組みを作る。
ひとつの答えはインターフェースかと思う。

public interface Kind {
    public String getName();   // 種別名を返す
}

で、種別に応じた実装クラスを用意する。

public class Kind0 implements Kind {
    public String getName() {
        return "大";
    }
}

public class Kind1 implements Kind {
    public String getName() {
        return "中";
    }
}

public class Kind2 implements Kind {
    public String getName() {
        return "小";
    }
}

public class Kind3 implements Kind {
    public String getName() {
        return "極小";
    }
}

これで元々マスターにあった「キーに応じた値」を得ることは出来る。

せっかくインターフェースにしたなら、冒頭にあった

    public void someProcess(Kind kind) {
        switch (kind) {
            case DAI:
                // 種別番号 0「大」 の時の処理
                break;

            case CYU:
                // 種別番号 1「中」 の時の処理
                break;

            case SYO:
                // 種別番号 2「小」 の時の処理
                break;
        }
    }

この種別が増えるたびに分岐が増える汚コードもすっきりさせられる。

インターフェースに、この時にするべき処理を定義する。

public interface Kind {
    public String getName();   // 種別名を返す
    public void someProcess(); // するべき処理
}

で、種別に応じた「するべき処理」を実装する。

public class Kind0 implements Kind {
    public String getName() {
        return "大";
    }
    public void someProcess() {
        // "大"の時にするべき処理
    }
}

public class Kind1 implements Kind {
    public String getName() {
        return "中";
    }
    public void someProcess() {
        // "中"の時にするべき処理
    }
}

public class Kind2 implements Kind {
    public String getName() {
        return "小";
    }
    public void someProcess() {
        // "小"の時にするべき処理
    }
}

public class Kind3 implements Kind {
    public String getName() {
        return "極小";
    }
    public void someProcess() {
        // "極小"の時にするべき処理
    }
}

そうすれば、汚コードもすっきりする。

    public void someProcess(Kind kind) {
        kind.someProcess();
    }

呼び出し元はインターフェースしか見えないので実際に何が実行されるかは、渡ってきたKindの実装クラスに応じて変わってくる。
変数kindはKind1のインスタンス参照かもしれないし、Kind2のインスタンス参照かもしれない。

実装はすっきりしたので、あとはインスタンスの生成だが、ここは局所化すれば汚コードでも良いと思う。

public class KindFactory {
    public static Kind create(int id) {
        switch (id) {
            case 0:
                return new Kind0();
            case 1:
                return new Kind1();
            case 2:
                return new Kind2();
            case 3:
                return new Kind3();
        }
        throw new IllegalArgumentException(id+"って何よ?");
    }
}

マジックナンバーが嫌だというなら、内部的なenumを使うのも良いかもしれない。

public class KindFactory {
    private enum K {
        DAI,    // 種別番号 0「大」 を表す
        CYU,    // 種別番号 1「中」 を表す
        SYO,    // 種別番号 2「小」 を表す
        GOKUSYO // 種別番号 3「極小」 を表す
    }

    public static Kind create(int id) {
        if (K.DAI.ordinal()==id) {
            return new Kind0();

        } else if (K.CYU.ordinal()==id) {
            return new Kind1();

        } else if (K.SYO.ordinal()==id) {
            return new Kind2();

        } else if (K.GOKUSYO.ordinal()==id) {
            return new Kind3();
        }
        throw new IllegalArgumentException(id+"って何よ?");
    }
}

いやいやそれでも条件分岐が多くて汚コードは嫌だと言うなら、idに応じたクラスをプロパティファイルに書いて、リフレクションでインスタンスを作ると条件分岐がなくて尚良しかと。

まとめ

そうは言っても状況によって求められることは違うので、ここで書いたことが絶対に正しいとも思わないし、プロダクトによって答えは変わってくるかと。

今更聞けない基礎英語

中学レベルに立ち返って基礎英語をまとめている。
このエントリーを随時更新する予定。

be動詞、一般動詞

be動詞

「~である」「~です」のように、主語と動詞以降の文がイコールであることを表現するのに用いるのがbe動詞。

■語順:

主語 + be動詞

■例:

・I am a travel journalist.
 → 私は旅行記者です

・You are a student.
 → あなたは生徒です

・He is a boss.
 → 彼はボスです


be動詞には以下の8種類がある。

be動詞
be
am
are
is
was
were
been
being

be動詞というだけあって、beが原形で、主語や時間軸などによって使い分ける。
be been being was were は一回忘れて、それ以外の am are is は主語によって下記のように使い分ける。

主語 be動詞
I am
you are
その他 is

■例:
・I am a travel journalist.
 → 私は旅行記者です

・You are a student.
 → あなたは生徒です

・He is a boss.
 → 彼はボスです


一般動詞

be動詞以外の、動作を表現するのに用いるのが一般動詞。

■語順:

主語 + 一般動詞

■例:

・I study English.
 → 私は英語を勉強する

・You speak English.
 → あなたは英語を話す

・He plays basketball.
 → 彼はバスケットボールをする


疑問文、否定文

be動詞の疑問文、否定文

be動詞を用いた疑問文はbe動詞を前に持ってくる

■語順:

be動詞 + 主語 + ・・・?

■例:

Are you a student?
 → あなたは生徒ですか?

be動詞を用いた否定文はbe動詞の後ろにnotを入れる

■語順:

主語 + be動詞 + not

■例:

・I am not a travel journalist.
 → 私は旅行記者ではありません

一般動詞の疑問文、否定文

一般動詞を用いた疑問文はdoを先頭に付ける

■例:

Do you speak English?
 → あなたは英語を話せますか?

一般動詞を用いた否定文はdo notを一般動詞の前に付ける

■例:

・You do not speak English?
 → あなたは英語を話せません


疑問詞

疑問詞には以下の8種類がある。

疑問詞 意味
how どのように
what
when いつ
where どこ
which どちら
who 誰が
whose 誰の
why なぜ

疑問詞は文の先頭に使用する。

■語順:

疑問詞 + ・・・

■例:

How to study English?
 → どのように英語を勉強する?

What is this?
 → これはですか?

When to arrive?
 → いつ到着しますか?

Where is this?
 → ここはどこですか?

Which is your pen?
 → どちらがあなたのペンですか?

Who is this?
 → これはですか?

Whose is this?
 → これは誰のですか?

Why Japanese people?
 → なぜなのだ日本人?


命令文

命令文には「~しなさい」と強い言い方から「~してください」や「~しましょう」なども含まれる。
共通して言えるのは「主語がない」ということ。
また命令文の否定形もある。

命令文「~しなさい」

主語を取り除き、動詞の原形が先頭に来る。

■語順:

動詞の原形 + ・・・

■例:

Study English.
 → 英語を勉強しなさい

be動詞の場合は、be動詞の原形のbeになる。

■例:

Be a good student.
 → 良い生徒になりなさい

否定命令文「~するな」

Do notを先頭につけて、Do not + 動詞の原形にする。

■語順:

Do not + 動詞の原形

■例:

Do not study English.
 → 英語を勉強するな

be動詞の場合でも、Do not を先頭につける。

■例:

Do not be a good student.
 → 良い生徒になるな

命令文(依頼)「~てください」

Pleaseを先頭につけて、Please + 動詞の原形にする。

■語順:

Please + 動詞の原形

■例:

Please study English.
 → 英語を勉強してください

命令文(勧誘)「~しましょう」

Let'sを先頭につけて、Let's + 動詞の原形にする。

■語順:

Let's + 動詞の原形

■例:

Let's study English.
 → 英語を勉強しましょう

三人称単数現在

一般動詞は、主語が三人称で、単数で、現在文の時だけsがつく。
(いわゆる「三単現のs」)
代名詞だと、He や She や It で、一般の名詞だと代名詞にした時に He や She や It になるものが対象。

■例:

・He plays basketball.
 → 彼はバスケットボールをする。

・My sister studes English.
 → 私の妹は英語を勉強する。
  (My sister は代名詞にすると She になる)

・Mr.Foo speaks English.
 → フーさんは英語を話す。
  (Mr.Foo は代名詞にすると He もしくは She になる)

以下の例は三人称単数現在ではないのでsはつかない。

■例:

I play basketball.
 → 私はバスケットボールをする。
  (一人称)

You play basketball.
 → あなたはバスケットボールをする。
  (二人称)

We play basketball.
 → 私達はバスケットボールをする。
  (複数

They play basketball.
 → 彼らはバスケットボールをする。
  (複数

・He played basketball.
 → 彼はバスケットボールをした。
  (過去)

・He will play basketball.
 → 彼はバスケットボールをする。
  (未来)

sのつけかた

一般動詞の最後が s sh ch x o の場合は es をつける。

■例:

・bless
 → blesses

・wash
 → washes

・watch
 → watches

・fix
 → fixes

・go
 → goes

子音 + yで終わっている場合 y を i にかえて es をつける。

■例:

・study
 → studies

・country
 → countries

その他は単純に s をつける。

■例:

・play
 → plays

・speak
 → speaks

例外で、have は has になる。

■例:

・have
 → has

現在進行形

現在行っていることを表す。
主語 + be動詞 + 動詞のing形
  ※be動詞が入るのに注意

■例:

・I am studying English.
 → 私は英語を勉強している

・You are speaking English.
 → あなたは英語を話している

・He is playing basketball.
 → 彼はバスケットボールをしている

動詞のing形

動詞に ing をつければ良い。

■例:

・study
 → studying

・speak
 → speaking

・play
 → playing

最後が e で終わる動詞は、その e を取って ing をつける。

■例:

・have
 → having

・use
 → using

・make
 → making

短子音 + 子音字で終わる動詞は、子音字を重ねる。

■例:

・run
 → running

・swim
 → swimming

・stop
 → stopping

・cut
 → cutting

疑問文

be動詞を前にする。

■語順:

be動詞 + 主語 + 動詞のing形 + ・・・?

■例:

Am I studying English?
 → 私は英語を勉強していますか?

Are you speaking English?
 → あなたは英語を話していますか?

Is he playing basketball?
 → 彼はバスケットボールをしていますか?

否定文

be動詞の後ろに not を入れる。

■語順:

主語 + be動詞 + not + 動詞のing形

■例:

・I am not studying English.
 → 私は英語を勉強していません

・You are not speaking English.
 → あなたは英語を話していません

・He is not playing basketball.
 → 彼はバスケットボールをしていません


助動詞

主語と動詞の間に置き、動詞の意味を助ける働きをする。

■語順:

主語 + 助動詞 + 動詞の原形

助動詞には以下のようなものがある。

助動詞 意味
can ~できる
may ~かもしれない
will ~する(未来形)
must ~するべき
■例:

・You can speak English.
 → あなたは英語を話すことができる

・You may speak English.
 → あなたは英語を話すかもしれない

・You will speak English.
 → あなたは英語を(将来的に)話す。

・You must speak English.
 → あなたは英語を話すべき

疑問文

助動詞を先頭に持ってくる。

■語順:

助動詞 + 主語 + 動詞の原形 + ・・・?

■例:

Can you speak English?
 → あなたは英語を話すことができますか?

May you speak English.
 → あなたは英語を話すかもしれなですか?

Will you speak English?
 → あなたは英語を(将来的に)話しますか?。

Must you speak English.
 → あなたは英語を話すべきですか?

否定文

助動詞の後ろに not を入れる。

■語順:

主語 + 助動詞 + not + 動詞の原形

■例:

・You can not speak English.
 → あなたは英語を話すことができない

・You may not speak English.
 → あなたは英語を話さないかもしれない

・You will not speak English.
 → あなたは英語を(将来的に)話さない

・You must not speak English.
 → あなたは英語を話すべきではない

Windows10にアップデートされないよう非表示にするWindowsUpdate更新プログラム番号(Windows7版)

以下を非表示に。
・KB2952664
・KB3021917
・KB3035583
・KB3112343

SQLiteのジャーナルモード

2つのSQLiteのデータベースファイルがあり、それぞれ更新すると一方は「-journal」ファイルが作成されて、もう一方は「-shm」と「-wal」ファイルが作成されるという違うファイルが作成される理由がわからず調べたら、ジャーナルモードが違ったというお話。

ジャーナルモードの大分

SQLiteのジャーナルモードは大きく分けて「delete」と「wal」がある。
「delete」の時は「-journal」ファイルが作成され、「wal」の時は「-shm」と「-wal」ファイルが作成される。
例えば「foo」というデータベースファイルがあると、ジャーナルモードが「delete」の時は「foo」というファイルの他に「foo-journal」というファイルが作成され、ジャーナルモードが「wal」の時は「foo-shm」と「foo-wal」というファイルが作成される。
どちらもジャーナルファイルなので、本体のデータベースにコミットするまでのデータが書き込まれるという意味では同じだが、動作は若干異なる。

ジャーナルモードの詳細は本家のサイトを参照。
http://www.sqlite.org/pragma.html#pragma_journal_mode

deleteモード

トランザクション開始から終了までの更新内容を「-journal」ファイルに書き込み、コミットしたときに本体のデータベースファイルへ更新内容を反映し、反映したら「-journal」ファイルを削除する。
最後の「-journal」ファイルを削除する動作に因んで「deleteモード」と呼んでいる。
コミットした時点でデータベースファイルを更新するため、大きなデータベースファイルの場合は書き込みに時間がかかるかもしれない。(未検証)

walモード

トランザクション開始から終了までの更新内容を「-shm」ファイルに書き込み、コミットした時に「-wal」ファイルへ更新内容を書き込む。
コミットした時点では本体データベースファイルには更新内容を書き込まないため、本体に比べて小さいファイルの更新でトランザクションを完了できるメリットがある。
なのでデータ更新が多いシステムではwalモードの方が有利と言える。(未検証)
ただしデータが本体データベースファイルとwalファイルに分散されるため、データの取得には時間がかかるかもしれない。(未検証)

walファイルはデータベース接続を閉じる時に、その内容を本体データベースファイルに反映する。
つまりクローズ処理はdeleteモードに比べて時間がかかる。

永続性の違い

先の通り、deleteモードはコミットした時点で本体データベースに更新を反映する一方、walモードではコミットしても本体データベースに更新を反映しない。
そのため、もしコミット後にシステムが異常終了等した場合、walモードでは本体データベースに更新を反映するためのリカバリが必要になる。

その他のジャーナルモード

上の2つ以外にも以下のようなジャーナルモードがある。

truncateモード

deleteモードの亜種で、コミットしても「-journal」ファイルを削除せず、0バイトのファイルを残しておく。
ファイル作成時の権限等のリスクを減らすには有利かもしれない。
データベースを閉じて再度接続するとdeleteモードになる。

persistモード

deleteモードの亜種で、コミットしても「-journal」ファイルの内容を削除せずに取っておく。
データベースを閉じて再度接続するとdeleteモードになる。

memoryモード

ジャーナルをファイルではなくメモリで管理する。
とにかく動作を速くしたい場合は選択する価値があるかもしれないが、メモリの容量に注意が必要かもしれない。
データベースを閉じて再度接続するとdeleteモードになる。

offモード

ジャーナリングしない・・・ということか?(未検証)

まとめ

deleteモードかwalモードはそれぞれメリット・デメリットがあるので、システムの特性に合わせて適切に使い分けましょう。