/* あとでなおす */

友達募集中

【CakePHP】プラグインの下にある設定ファイルをプラグイン以外から読み込む

CakePHP で設定ファイルは通常「app/Config/coinfig.php」に置き*1、その設定ファイル内に複数個の設定を記載することができます。

$config = array(
  'name' = '山田 太郎',
  'hobby' = array('Game', 'Music'),
  'family' = array(
    'father' = '山田 勤',
    'mother' = '山田 巴',
  ),
)

呼び出す場合には以下のように記載します。
上記ではfamilyの部分が配列の中に配列を記載していますが、その場合はドットで階層区切りで書くことで呼び出せます。
もちろん3階層以上も呼び出すことも可能*2ですし、取得した結果を変数に保持することも可能です。
ここらへんの階層については詳細な説明をしているブログ等も多数あるので、そちらを参照した方がよろしいかと思います。

Configure::load('config');

class testClass {
  public function main() {
    // 名前を取得
    $name = Configure::read('name');
    // 趣味を配列で取得
    $hobby = Configure::read('hobby');
    // 家族を連想配列で取得
    $family = Configure::read('name.family');
    // 家族の中から母親を取得
    $mother = Configure::read('name.mother');
  }
}

ここで問題になってくるのはプラグイン(Plugin)を使用している場合のConfigの呼び出し方です。
使用している方はご存知かと思いますが、プラグインの下にある設定ファイルは「app/Config/coinfig.php」ではなく「app/Plugin/対象のプラグイン名/Config/config.php」にあります。プラグイン内にあるモデルやコントローラなどから同一プラグインにある設定ファイルを呼び出す場合には上記と同じ書き方で良いですが、プラグイン外から呼び出す場合には下記のようにあらかじめプラグインフォルダを指定してロードする必要があります。

下記のコードは上記に記載した設定ファイルと同じ内容の設定ファイルが「app/Plugin/TestApp001/Config/config.php」「app/Plugin/TestApp002/Config/config.php」の異なるプラグインにある前提とします。
TestApp001の設定ファイルを読み込んだ後にTestApp002の設定ファイルを読み込んでいます。

class testClass {
  public function main() {
    // app/Plugin/TestApp001/Config/config.php をロード
    Conigure::load('TestApp001.config');
    
    // app/Plugin/TestApp001/Config/config.php から名前を取得
    $name = Configure::read('name');
    // app/Plugin/TestApp001/Config/config.php から趣味を配列で取得
    $hobby = Configure::read('hobby');
    // app/Plugin/TestApp001/Config/config.php から家族を連想配列で取得
    $family = Configure::read('name.family');
    // app/Plugin/TestApp001/Config/config.php から家族の中から母親を取得
    $mother = Configure::read('name.mother');
    
    
    // ここでPlugin/TestApp001/Config/config.php から読み込んだ設定情報を破棄
    // Configure::checkで存在確認し、存在する場合のみConfigure::deleteで削除
    if (Configure::check('name')) {
        Configure::delete('name');
    }
    if (Configure::check('hobby')) {
        Configure::delete('hobby');
    }
    if (Configure::check('name.family')) {
    	Configure::delete('name.family');
    }
    if (Configure::check('name.mother')) {
    	Configure::delete('name.mother');
    }
    
    
    // app/Plugin/TestApp002/Config/config.php をロード
    Conigure::load('TestApp002.config');
	
    // app/Plugin/TestApp002/Config/config.php から名前を取得
    $name = Configure::read('name');
    // app/Plugin/TestApp002/Config/config.php から趣味を配列で取得
    $hobby = Configure::read('hobby');
    // app/Plugin/TestApp002/Config/config.php から連想家族を配列で取得
    $family = Configure::read('name.family');
    // app/Plugin/TestApp002/Config/config.php から家族の中から母親を取得
    $mother = Configure::read('name.mother');
  }
}

 

上記からわかるように1つ目のポイントは「Conigure::load('対象プラグイン名.config');」でロードしてから読み込むことです。
2つ目のポイントはTestApp002をロードする前にTestApp001で読み込んだ設定を破棄していることです。
破棄しないと例えばTestApp002の「$name = Configure::read('name');」の時にロード済みの全ての設定ファイルのうちキーが「name」になっている設定を読み込んでしまうためTestApp001とTestApp002の両方の設定を取得してしまいます。 2回読み込んでもTestApp002のnameで基本的には上書きされるのでそれほど問題ありませんが、例外的に配列のみはなぜか上書きではなく要素追加になるので、上記の例だとhobbyを破棄せず2回読み込むと $hobby = array('Game', 'Music', 'Game', 'Music') のようになってしまいます。
これは文字列などの単一項目や連想配列のようにキーがある場合には発生しません。
またプラグイン違いでも設定ファイルのキーが重複しなければ破棄する必要はありません。

このプラグインの設定ファイルの呼び出しはバージョンがあまりにも古いとサポートされていませんが、PHPは5.0以上でCakePHPは2.0以上ならばサポート済み*3です。

*1:ファイル名は「coinfig.php」以外でも可能ですが、読み込み時の書き方が変わったり保守的にもどこに設定が書いてあるのかがわかりにくかったりするのでファイル名を変更することはお勧めしません。

*2:階層の数に上限はあるかもしれませんがそこらへんは不明です。4階層くらいまでなら書いたことがあるので少なくとも人間が読めるレベルくらいの階層まで行けるはずです。

*3:うろ覚えなので外れていたらごめんなさい。

【SQL Server】トリガー一覧取得SQL

SQL Serverでテーブルトリガーの一覧を取得するSQLです。
たまに使うのでメモ。

Management Studioってトリガーを確認しにくいんですよね。


他システムをメンテや障害対応してくれとか言われたときにトリガー誤爆したくないで私はSQL Serverの場合はこのSQLを最初の方に実行します。
トリガーの多さでDBの保守性って大きく変わってきますからね…

SELECT sys_tbl.name AS テーブル名
, sys_trg.name AS トリガー名
, sys_trg_ev.type_desc AS トリガータイプ
, CASE sys_trg.is_disabled WHEN 0 THEN '有効' ELSE '無効' END AS 有効無効
, 'ALTER TABLE ' + sys_tbl.name + ' DISABLE TRIGGER ' + sys_trg.name + ';' AS トリガー無効化SQL
, 'ALTER TABLE ' + sys_tbl.name + ' ENABLE TRIGGER ' + sys_trg.name + ';' AS トリガー有効化SQL
FROM sys.triggers AS sys_trg
INNER JOIN sys.tables AS sys_tbl
ON sys_trg.parent_id = sys_tbl.object_id
INNER JOIN sys.trigger_events AS sys_trg_ev
ON sys_trg.object_id = sys_trg_ev.object_id
;

【説明】
テーブル名とトリガー名は名前通りです。
トリガータイプは更新の種類で INSERT / UPDATE / DELETE のいずれかです。
有効無効も名前通りですがトリガー自体が有効か無効になっているかです。
無効の場合はトリガーが存在しても動きません。
有効無効の切り替えのSQLも最後の2列で取得しています。

※トリガーが1つでも例えばUPDATE兼DELETEトリガーだったりすると2行で表示されますのであしからず。

【こちうさ】Rabbit House Tea Party 2016【I am 難民】

今更ですが「ご注文はうさぎですか??」のRabbit House Tea Party 2016に行ってきました。

自分は夜の部のみ参加しました。

参加された方、お疲れ様でした。

 

感想はもう、「最高!」の一言に限ります。

自分の好きなキャラが目の前でお話ししているだけで

声優さんのイベントには今まであまり参加したことがありませんでしたが、ここまで楽しめて非常に満足しています。

 

さすがに遠方からの参加なので物販という朝一の戦場までは足を運びませんでしたが、

会場には色々な展示物があってそれだけでも満足です(^ω^)

等身大の魔法少女チノちゃんが可愛かった…

 

元々一人での参加に加えてコミュ障が発揮してイベント中はずっと一人でしたが、

Twitterとか見る限り自分以外にも遠方から参加されている方多いんですね。

 

スペシャルエピソードの制作も決定したので、ぜひまたイベントがあったら参加したいです♪

※イベントあってもチケット当たる気がしないですが…

 

それではまたノシ

f:id:nanashipgmer:20160512000949j:plain

f:id:nanashipgmer:20160512002647j:plain

f:id:nanashipgmer:20160512002650j:plain

f:id:nanashipgmer:20160512002653j:plain

【ひとりごと】全然ブログ更新していないね

ブログ更新してなかったから更新しよう。

最終更新が2年前とかになってた…

【C#】Crestal Reports の初回起動を早くしてみよう【SAP】

帳票で使用されるクリスタルレポートの初回ロードがどうにも遅いので、早くしてみようというわけです。

実際には初回を早くするのではなく、プログラム起動時などマルチスレッドにてダミーのクリスタルレポートをロードする→ユーザがクリスタルレポートを初回起動しているつもりでもプログラム起動時にすでにロード済みなのでロードに時間がかからないといううっさん臭いプログラムです。

言語はC#、以下サンプルです。

 

  1. using System.Threading;
  2. using CrystalDecisions.CrystalReports.Engine;
  3.  
  4. class XXX()
  5. {
  6.   static void Main()
  7.   {
  8.   // マルチスレッドで CrystalReports の読み込み
  9.   Thread thread = new Thread(LoadCrystalReports);
  10.   thread.Start();
  11.   }
  12.   private void LoadCrystalReports()
  13.   {
  14.     using (ReportClass report = new DummyReport())
  15.     {
  16.       report.Load();
  17.     }
  18.   }
  19. }

【SQL Server】SUM()使用時のオーバーフローについて

会社でちょっと引っかかったのでメモ

○ SELECT SUM(2147483647);
○ SELECT SUM(2147483648);
× SELECT SUM(2147483647 + 1);

 

2147483647…SQL Server の integer 型の最大値

 

2147483648 = 2147483647 + 1 でありますが、上記の通り2行目のクエリは成功しているのに対し3行目のクエリは「expression をデータ型 int に変換中に、算術オーバーフロー エラーが発生しました。」とエラーになります。

 

まだ検証していないので憶測ですが SUM は () 内の最初の値から () 内の値の型を暗黙的に判定しているためかと思われます。

2行目は 2147483648 = bigint(かな?) と判定しているため integer の最大値より大きな値がが入っても落ちませんでした。

しかし、3行目は 2147483647 = integer と判定していますが + 1 をしているために integer 型の最大値超えでオーバーフローになったのかと思われます。

 

下記のように書くとオーバーフローになりません。

 

SELECT SUM(CAST(2147483647 AS BIGINT) + 1);

【Microsoft Windows 8】デュアルディスプレイ(拡張)でスタートメニューを表示するディスプレイを変更

Win + PageUp(もしくは PageDown) キーで変更します。

[コントロールパネル] → [画面の改造解像度] → [これをメインディスプレイにする] にチェックを入れた場合メインディスプレイを変更できますが、スタートメニューの出力ディスプレイを変更できません。

この変更で Win + C キー によって出現されるチャームの出力ディスプレイも同様に変更されます。

(※カーソルを右端に当ててチャームを出現させるのはどのディスプレイでも可能です)

スタートメニューの出力やチャームの出現を複数のディスプレイで同時に行うことは出来ないみたいですね。(いらないかそんな機能…)

 

参考

http://answers.microsoft.com/ja-jp/windows/forum/windows_8-desktop/windows-8/4014e7b4-7e57-45fa-831e-278e4a92ec23