2012年8月25日土曜日

Ubuntu で文字入力するときに全角アルファベットになってしまうときの対処法


日本語入力できなくなって
超ムカつくんですけど!!

そんなときは
Shift + 無変換(スペースキーの左隣)
を入力すると、日本語入力できるようになりました。

Ubuntu 12.04 にて dotCloud の MySQL を試してみる (PHP編)


二回続けてのdotCloudエントリ
本エントリはUbuntu 12.04 にて dotCloud の MySQL を試してみる (コマンドライン編) の続きです。
前回はコマンドラインで、helloworldサービスを作り、データベースとテーブルを作って、データをINSERTするところまでやりました。

今回はPHPからMySQLを操作してみます。

このエントリの目次
  1. PHP + MySQLのサービスにする
  2. environment.json
  3. PHPでMySQLに接続する
  4. PHPでMySQLを操作する
  5. 参考にさせて頂いたサイト
  6. さいごに

1.PHP + MySQLのサービスにする
dotcloud.ymlを下のように書きます。
my_www:
    type: php 
my_database:
    type: mysql
my_wwwmy_database は好きな文字列を指定できます。
あとは、下のコマンドを打てばOKです。
dotcloud push helloworld
# upload ~/work/dotcloud/helloworld ssh://dotcloud@uploader.dotcloud.com:443/helloworld
# rsync
building file list ... done
./
(中略)
Deployment finished. Your application is available at the following URLs
my_www: http://helloworld1-windblue.dotcloud.com/
www: http://helloworld-windblue.dotcloud.com/

2.environment.json
dotCloudにはenvironment.jsonという設定ファイルがあり、そこに色々な情報が入っています。
ホスト名やポート番号などのMySQLに関する情報も入っていて、それらはDOTCLOUD_MY_DATABASE_MYSQL_XXXというキーに格納されています。

PHPからMySQLに接続するにあたって、その設定ファイルを確認します。

詳しくはdotCloudのドキュメントにも載っているのでそちらも参照して下さい。

PHPからenvironment.jsonを確認
ローカルにてdotcloud.ymlと同じディレクトリにindex.phpを作り、下のようなソースを書いて dotcloud push します。
<?php

// environment.json ファイルから接続に必要な情報を取得
$filepath = $_SERVER['HOME'].'/environment.json';

$env = json_decode(file_get_contents($filepath), true);
foreach ($env as $key => $value) {
    print_r($key . "=" . $value . "<br />");
}

作ったページにアクセスすると、設定値一覧が見れます。

SSH接続して直接environment.jsonを確認
PHPからじゃなくても、直接dotCloudのサーバに入って確認することもできます。
下のコマンドでサーバに入ります。
dotcloud ssh helloworld.my_www
helloworld.my_wwwは <作ったサービス名>.<dotcloud.ymlに書いたキー です。

サーバに入ると、カレントディレクトリは
/home/dotcloud/
になります。
ls コマンドで見ると、environment.json がありました。
$ ls
code  current  environment.json  environment.yml  php-env  revisions  rsync-1345870675271

environment.yml というファイルもありましたが、内容は大体同じのようです。

3.PHPでMySQLに接続する
index.php を下のように書けばOKです。
<?php

// environment.json ファイルから接続に必要な情報を取得
$filepath = $_SERVER['HOME'].'/environment.json';

// 'DOTCLOUD_MY_DATABASE_MYSQL_MYSQL_XXX' というキーでMySQL関連のデータが入っている
$host = $env['DOTCLOUD_MY_DATABASE_MYSQL_HOST'];
$user = $env['DOTCLOUD_MY_DATABASE_MYSQL_LOGIN'];
$pass = $env['DOTCLOUD_MY_DATABASE_MYSQL_PASSWORD'];
$port = $env['DOTCLOUD_MY_DATABASE_MYSQL_PORT'];

//前回のエントリで作成したデータベース「nujabes」
$dbName = 'nujabes';

//mysqliオブジェクト作成
$mysqli = new mysqli($host, $user, $pass, $dbName, $port);

PDOで接続したい場合はDotCloudでのMySQL,Redis,MongoDBの使い方 | Rest Termが非常に参考になります(ただしenvironment.jsonの、MySQLに関するキーが古いようですので そこだけご注意を)。
4.PHPでMySQLを操作する
もうあとは通常のMySQL操作と同様です。
//前回のエントリで作成した「songs」というテーブルから全行取得するSQLを発行
$result = $mysqli->query('SELECT * FROM songs;');

//結果を取得していく
$rows = array();
while ($row = mysqli_fetch_assoc($result)) {
    $rows[] = $row;
}

//実行結果を表示
print_r($rows);
これで作ったページにアクセスすると、
Array ( [0] => Array ( [id] => 0 [title] => Luv (Sic) Pt. 2 ) )
と表示されます。

やったね!

5.参考にさせて頂いたサイト
  1. DotCloud で PHP アプリを設置してみたときの色々 | 肉とご飯は甘いもの @ sotarok
  2. DotCloudでのMySQL,Redis,MongoDBの使い方 | Rest Term

5.さいごに
あとはnginx、cronの使い方を覚えれば、超基本的なバックエンドサービスは実現できそうです。
PHP のフレームワークはどうするかと悩んでいるところですが…。

あと、少し日付が古いですが、dotcloudのpostgres(たぶんmysqlも)はデフォルトで全接続を許可するので気をつけよう | uuu という不穏な記事も見つけたので、こちらも確認していきます。

それでは。

2012年8月24日金曜日

Ubuntu 12.04 にて dotCloud の MySQL を試してみる (コマンドライン編)


久しぶりのdotCloud
超久しぶりです。

ちょっとやりたい事ができて、バックエンドをdotCloudで実装しようと思ったので触ってみました。

このエントリの目次
  1. dotCloudの導入
  2. MySQLつきのサービスをデプロイする
  3. MySQLをコマンドラインから触ってみる
  4. さいごに
1.dotCloudの導入
dotCloud の導入については、当ブログの DotCloud + PHPで「Hello World」をUbuntu 11.04で試してみた に書いてるので、そちらをご参照下さい。

2.MySQLつきのサービスをデプロイする
まずは適当にhelloworldディレクトリを作ってその中に移動します。
$ mkdir helloworld
$ pwd
~/work/dotcloud/helloworld

そこでdotcloud.ymlという名前で下記のような設定ファイルを作ります。
my_database:
    type: mysql

「my_database」は好きな文字列を指定できます。

あとはサービスを作成して、dotCloudに同期させるだけでOKです。

まずサービスの作成。
helloworld という名前で作成します。
$ dotcloud create helloworld
Created application "helloworld" using the flavor "sandbox" (Use for development, free and unlimited apps. DO NOT use for production.).
This flavor cannot be changed.

** YOU HAVE CREATED A SANDBOX APPLICATION **
SANDBOX applications may not be scaled, may not use custom domains,
and do not have the same performance guarantees as "live" applications.
SANDBOX applications cannot be upgraded.

Information about the different flavors offered can be found here:
http://docs.dotcloud.com/guides/flavors/

そしてdotCloudに同期。
$ dotcloud push helloworld
# upload ~/work/dotcloud/helloworld ssh://dotcloud@uploader.dotcloud.com:443/helloworld
# rsync
building file list ... done
./
dotcloud.yml

sent 148 bytes  received 34 bytes  28.00 bytes/sec
total size is 29  speedup is 0.16
16:31:09 ---> Deploy of "helloworld" scheduled for revision rsync-1345739468475 at 2012-08-23 16:31:09
16:31:09 ---> Building the application...
16:31:09 ---> Nothing to build
16:31:09 ---> Initializing new services... (This may take a few minutes)
16:31:09 ---> Using default scaling for service my_database (1 instance(s)).
16:31:09 [my_database.0] Initializing...
16:31:24 [my_database.0] Service initialized
16:31:25 ---> Deploy finished

Deployment finished. Your application is available at the following URLs
No URL found. That's ok, it means that your application does not include a webservice.

3.MySQLをコマンドラインから触ってみる
下記のコマンドでMySQLの対話モードに入ります。
$ dotcloud run helloworld.my_database -- mysql
# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.1.41-3ubuntu12.10-log (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
コマンド中のhelloworld.my_databaseは、<createしたサービス名>.<dotcloud.ymlに記述したMySQLのキー>に相当します。

で、まずはデータベースを作って。
mysql> CREATE DATABASE nujabes;
Query OK, 1 row affected (0.00 sec)

作ったデータベースを使います。
mysql> use nujabes;
Database changed

そのデータベース中にテーブルを作って。
mysql> CREATE TABLE songs(id INT(10), title VARCHAR(64));
Query OK, 0 rows affected (0.04 sec)

値を入れてみます。
mysql> INSERT INTO songs(id, title) VALUES(0, 'Luv (Sic) Pt. 2');
Query OK, 1 row affected (0.01 sec)

SELECT文で確認します。
mysql> SELECT * FROM songs;
+------+-----------------+
| id   | title           |
+------+-----------------+
|    0 | Luv (Sic) Pt. 2 |
+------+-----------------+
1 row in set (0.00 sec)

簡単でした。

4.さいごに
慣れたら3分で構築できそうです。

次のエントリではPHPからMySQLを操作してみます。

2012年8月13日月曜日

UITableView でセクションが複数ある場合の複数選択&削除を実装してみた


すごい面倒くさかった
セクションが1つだけの場合は簡単なのですが、セクションが複数存在するようになった途端に面倒くさくなります。

サンプルを書いてみました。
UITableViewの見た目はデフォルトです。
各セクションで行の数が0になると、そのセクションも削除するようにしました。

けっこうきれいに、滑らかなUIで実現できました。

このエントリの目次
  1. サンプルコード
  2. 複数選択の方法
  3. 選択したセルの取得
  4. データの削除
  5. UITableViewの表示からも削除
  6. 空になったセクションの削除
  7. さいごに

1.サンプルコード
githubにあげました。
2.複数選択の方法
self.tableView.allowsMultipleSelectionDuringEditing = YES;
とすると、編集モードのときに複数選択ができるようになります。

3.選択したセルの取得
[self.tableView indexPathsForSelectedRows];
とすると、indexPath(sectionとrowがセットになったオブジェクト)のNSArrayが取得できます。

ここで注意点ですが、sectionやrowの順ではなく、選択した順に配列にindexPathが格納されています。

4.データの削除
ここからは、データの構成によって処理方法は変わると思います。
本サンプルではループをまわして、セクション毎に行を一括削除しています。
gIthubのこのクラスの123行目からにあたります。

以下長いですが、サンプルの抜粋します。
    //「選択したセルたちのindexPath」が配列のかたちで取得できる
    NSArray *indexPaths = [self.tableView indexPathsForSelectedRows];
    
    //選択されたセルが含まれるセクション番号一覧を取得(値の重複はさせない)
    NSMutableSet *selectedUniqueSections = [NSMutableSet set];
    for (NSIndexPath *tempIndexPath in indexPaths) {
        [selectedUniqueSections addObject:[NSNumber numberWithInteger:tempIndexPath.section]];
    }
    
    //各セクション番号と、それに紐づく行番号たちをdictionary形式で取得
    NSMutableDictionary *selectedSectionAndRows = [NSMutableDictionary dictionary];
    for (NSNumber *selectedSection in selectedUniqueSections) {
        NSMutableArray *selectedRows = [NSMutableArray array];
        
        for (NSIndexPath *indexPath in indexPaths) {
            if (indexPath.section == [selectedSection intValue]) {
                NSArray *tableDataRow = [[tableData objectAtIndex:indexPath.section] objectForKey:KEY_ROW];
                NSString *selectedRowValue = [tableDataRow objectAtIndex:indexPath.row];
                [selectedRows addObject:selectedRowValue];
            }
        }
        [selectedSectionAndRows setObject:selectedRows forKey:selectedSection];
    }
    
    //各セクション毎に、その中の行を一括で削除する
    for (NSNumber *section in selectedSectionAndRows) {
        NSInteger sectionInteger = [section intValue];
        NSArray *selectedRow = [selectedSectionAndRows objectForKey:section];
        [[[tableData objectAtIndex:sectionInteger] objectForKey:KEY_ROW] removeObjectsInArray:selectedRow];
    }

5.UITableViewの表示からも削除
以下サンプルの抜粋。
    //UITableViewの表示からも削除する
    [self.tableView beginUpdates];
    [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
    [self.tableView endUpdates];

6.空になったセクションの削除
本サンプルではループをまわしてセクション毎に行数を数え、ゼロだったセクションを削除しています。

以下にサンプルの抜粋をします。
    //セクション中の行が0になった場合、削除する
    NSMutableIndexSet *zeroRowSections = [NSMutableIndexSet indexSet];
    for (NSInteger i = 0; i < [tableData count]; i++) {
        if ([[[tableData objectAtIndex:i] objectForKey:KEY_ROW] count] == 0) {
            [zeroRowSections addIndex:i];
        }
    }
    
    //行数がゼロのセクションがあれば、そこのデータを一括削除し、表示をリロードする
    if ([zeroRowSections count] > 0) {
        [tableData removeObjectsAtIndexes:zeroRowSections];
        [self.tableView reloadData];
    }
7.さいごに
かなり面倒くさかったんですが、きれいなUIを実現できました。

というか泥臭すぎる気がするんですが、データの持ち方がよくないような気がします。
複数セクションの場合、どのようにデータを持てば簡単に処理ができるのでしょうか…

参考になれば幸いです。
それでは。

2012年8月7日火曜日


Related Posts Plugin for WordPress, Blogger...