Downloads - android-wifi-tether - Project Hosting on Google Code: "Wireless Tether for Root Users"
マーケットにあるテザリングアプリでは不安定なので、上記にある最新のアプリを入れたところさっくさくに動くじゃないかー♪♪
今回自分が入れたのは
wireless_tether_2_0_5-RC2.apk
2010年12月28日火曜日
やっとGalaxySを手に入れた。。。
発売日を逃して手に入らず、今となってはどうしようかも迷いながらズルズル昨日までやってきました。。
ついに購入♪
やっぱりサクサクっす!!
これでやっとUnlax Noteのデバッグができる。。。
ついに購入♪
やっぱりサクサクっす!!
これでやっとUnlax Noteのデバッグができる。。。
2010年12月21日火曜日
「Partuza」の読み方は「パルトゥーザ」
partuza - Project Hosting on Google Code
PartuzaをGoogle翻訳に入れて言語を検出するを選択する。
すると、どうやら「Partuza」はスペイン語のよう。。
何故か日本語には翻訳できない。。
とりあえず「Partuza」の音声を聞いてみた。
「パルトゥーザ」??
PartuzaをGoogle翻訳に入れて言語を検出するを選択する。
すると、どうやら「Partuza」はスペイン語のよう。。
何故か日本語には翻訳できない。。
とりあえず「Partuza」の音声を聞いてみた。
「パルトゥーザ」??
2010年11月12日金曜日
第2弾Googleブランドフォン「Nexus S」の画像がついに登場。Gingerbread搭載機種として年内発売か?
第2弾Googleブランドフォン「Nexus S」の画像がついに登場。Gingerbread搭載機種として年内発売か?
良いな~これ。
ほしいな~
有機EL不足でGalaxy Sが手に入らない間に入った情報だけに、Galaxy S買うのためらうな。。
SIMフリー携帯を日本で利用した際の情報がまとめられてるサイト無いかな。。
良いな~これ。
ほしいな~
有機EL不足でGalaxy Sが手に入らない間に入った情報だけに、Galaxy S買うのためらうな。。
SIMフリー携帯を日本で利用した際の情報がまとめられてるサイト無いかな。。
2010年10月21日木曜日
Oracle テーブル定義、カラム情報の確認方法
user_tab_columns テーブルを参照して確認して面倒やな。。。
って言ってたらもっと楽な方法を教えられた(笑)
DESC [table_name];
これだけでOK。。
おいおい(笑)
その他、
SHOW ALL;
で詳細な環境情報を確認もできる。
って言ってたらもっと楽な方法を教えられた(笑)
DESC [table_name];
これだけでOK。。
おいおい(笑)
その他、
SHOW ALL;
で詳細な環境情報を確認もできる。
2010年10月20日水曜日
Oracle sqlplusから接続の際には文字コードを指定しておこう from Linux
NLS_LANGの設定
Linuxからsqlplusを利用してOracleサーバーにpsqlみたいに接続しようとした場合に mysql の set names utf8; みたいなものは無いのかと探してて見つけた。
sqlplusで接続してからの方法は残念ながら見つけられなかったが、接続する前に export で環境変数(?)を指定する事で可能だった。
今回はUTF8で見たかったので、
$ export NLS_LANG=Japanese_Japan.UTF8
をコマンド入力して解決した。
2010年10月19日火曜日
Windows PHPインストールパッケージの選び方
Hello, earth! : PHP5.3のインストール
よく忘れるねんなこれ。。。
VC9とVC6の違い
VC9 = IIS用
VC6 = Apache用
Non Thread Safe と Thread Safe の違い
Non Thread Safe = モジュール版
Thread Safe = CGI版
あ~ 今回もスッキリ♪♪
って駄目や。。。
NTS版にはphp5apache2_2.dllが入っていない。。
Apache1.0用しかない。。
逆か!?
とりあえず TS版を利用する事にしよう。。。
って駄目や。。。
NTS版にはphp5apache2_2.dllが入っていない。。
Apache1.0用しかない。。
逆か!?
とりあえず TS版を利用する事にしよう。。。
2010年10月8日金曜日
ドコモ版 Galaxy Sにはストロボライトが無い
Samsung Fascinate(Verizon版Galaxy S)
どうしても比べてしまうのがiPhone4との比較。
また一つ発見してしまった。。。
ドコモ版GalaxySにはストロボライトが無い。。。
あ~ また嫌なところに気づいてしまう。。。
どうしよう。。。 買おうかな。。。
さすがにHT-03Aよりかは良いしな。。。
2010年10月6日水曜日
GALAXY Sには本当はインカメラが付いていたのに。。。
ドコモ、Android 2.2搭載スマートフォン「GALAXY S」10月下旬発売 - ケータイ Watch
またベースバンドチップが違うって事は海外のカスタムROMも入れれないって事なのかな。。。
ここの記事を見るとどうやらドコモのGALAXY Sにはインカメラが無いみたい。。。
別に必須では無いけど付いてる物をわざわざ取るなよ。。。
iPod Touchでも付いてるのに。。。
またベースバンドチップが違うって事は海外のカスタムROMも入れれないって事なのかな。。。
2010年10月5日火曜日
Windows XP 環境からコマンドでOracleに接続してみる。Instant Clientを利用
まずは下記から
2つをダウンロードして解凍する。
instantclient-basic-win32-11.2.0.1.0.zip (51,458,190 bytes)
instantclient-sqlplus-win32-11.2.0.1.0.zip (758,913 bytes)
インストーラー等は無い。
解凍したファイルは2つとも下記ディレクトリの中に展開された状態となる。
※ならない場合は自分で合わせてください。
instantclient_11_2
次にこのディレクトリを任意の場所に移動します。
自分の場合は
D:\usr\local\instantclient_11_2
としました。
そしたら次にsqlplusコマンドがパス指定しなくて良いように、システム環境変数のPathに
D:\usr\local\instantclient_11_2
を追加します。
あと TNS_ADMIN というシステム環境変数も追加します。
変数名= TNS_ADMIN
変数値= D:\usr\local\instantclient_11_2
これでセットアップ完了になるので、コマンドプロンプトからLinuxと同様にsqlplusコマンドで接続する。
sqlplus [username]/[password]@[host]:1521/[sid]
Android 2.2、スーパー有機EL搭載――ドコモ、「GALAXY S」を発表 - ITmedia D モバイル
Android 2.2、スーパー有機EL搭載――ドコモ、「GALAXY S」を発表 - ITmedia D モバイル
ここの記事によるとテザリングはやっぱり無いみたいですね。。。
でも安心??
ここで見る感じでは2.2のroot権限も既に取れているようなので、これでテザリングできますね♪
よし買おう~♪
変に最初から付いててオプション料金設定されてるよりこっちの方が良いかな。。。
Oracle Instant Client for Linux を利用して接続してみる
Oracle Instant Client for Linux を試してみる
上記を参考にやってみた。
libsqlplus.so
が置いてあるディレクトリを環境変数に追加する。
export LD_LIBRARY_PATH=[libsqlplus.soファイルが置いてあるディレクトリパス]
その後
./sqlplus [username]/[password]@[host]:1521/[SID]
として接続する。
これで
SQL>
が表示されて接続されている事が確認できる。
「ドコモ スマートフォン GALAXY S」「ドコモ スマートフォン GALAXY Tab」を開発
報道発表資料 : 「ドコモ スマートフォン GALAXY S」「ドコモ スマートフォン GALAXY Tab」を開発 | お知らせ | NTTドコモ
非常に残念です。。。
テザリングについて触れられていません。。。
恐らくこれはテザリング機能が使えなく制限されている事を意味するんでしょうね。。。
せっかく2.2なのに。。。
値段は65000円位でしょうか。。。
あ~ どうしよう。。。
テザリングショックだな。。。
Xperiaもテザリングできるようになったし、GalaxySもテザリングの方法を誰かが見つけてからにしようかな。。。
2010年10月4日月曜日
Zend_Date 年の指定に気をつけろ!!
ylog � Zend_Date 2008-12-29 問題!?: "yyyy"
このページでは問題となっているけど、問題ではありません。
大文字指定のYYYYだとISO準拠になってその週で年が変わる場合週頭から変わるという変な仕様だったはず。。。
要注意ですね。。。
フリスクでiPhoneスタンドが作れるよ♪
Isettaのりたまこ と BMWイセッタ300☆ ドラとテッテケ~♪ フリスクでiPhoneスタンドが作れるよ♪
これやりたいがためにフリスク急いで食べたよ。。。
取り敢えず気は済んだけど2回目置く時大変ですね。。。
PCIデータセキュリティスタンダード - Wikipedia
PCIデータセキュリティスタンダード - Wikipedia
PCI-DSSは常識なのか?
これは参加企業の名前を見ても解る通り支払いが発生する仕組みのところだけなのかな?
でも基準や認識を合わせるための資料としては十分なのか。。
ん~参加企業の名前はもちろんビッグなので、これを基準とするのが良いんだろうな。。。
2010年9月28日火曜日
Android スター・ウォーズの「DROID R2-D2」携帯、米で登場 - ITmedia News
Android スター・ウォーズの「DROID R2-D2」携帯、米で登場 - ITmedia News
まったしょうもない事を(笑)
好きな人は好きなんでしょうね~こういうの(笑)
そういえば会社の人でAndroidを進めても断固としてキーボードが無いから嫌という人がいますね。。。
これ日本で出たら無理やり買わせたいな。。。(笑)
なんでアメリカであんなに人気あったのに日本でDROID出なかったんでしょうか。。。
まったしょうもない事を(笑)
好きな人は好きなんでしょうね~こういうの(笑)
そういえば会社の人でAndroidを進めても断固としてキーボードが無いから嫌という人がいますね。。。
これ日本で出たら無理やり買わせたいな。。。(笑)
なんでアメリカであんなに人気あったのに日本でDROID出なかったんでしょうか。。。
どうやら Galaxy S はタッチセンサーが特に良いらしい
上記の動画見ると解る通り、Galaxy Sの方だとXやY座標が近くなっても同一とみなされていない。
というか普通そういうものじゃないの?って気はしますが、どうやらそうじゃないようです(笑)
ハードの問題のようですがiPhoneはどうなんでしょうね。。。
2010年9月27日月曜日
メモアプリリリースしてみました
どうも自分はEvernoteが好きではなくて、Googleが同様のサービスを展開してくれないかなって待ってたんですが、待ちくたびれたので、自分で作ってみました。
Google Docs APIを理由上Android2.1以上じゃないと動作しないようですが。。。
内容的には今はただGoogleドキュメントをメモ帳変わりに使っている自分のためだけのアプリって感じですが、将来的にはちゃんと見た目も綺麗にしてみんなに使ってもらえるようにしていきたいです。
またアップデートしたらここでも報告しようと思います。
アプリ名: アンラックスノート
パッケージ名: com.unlax.note
です。興味あれば。。。 今は酷い状態ですが(笑)
Google Docs APIを理由上Android2.1以上じゃないと動作しないようですが。。。
内容的には今はただGoogleドキュメントをメモ帳変わりに使っている自分のためだけのアプリって感じですが、将来的にはちゃんと見た目も綺麗にしてみんなに使ってもらえるようにしていきたいです。
またアップデートしたらここでも報告しようと思います。
アプリ名: アンラックスノート
パッケージ名: com.unlax.note
です。興味あれば。。。 今は酷い状態ですが(笑)
2010年9月24日金曜日
NTTドコモ、10月5日にGalaxy S SC-02Bを発表予定
juggly.cn NTTドコモ、10月5日にGalaxy S SC-02Bを発表予定
まじですか!!
楽しみです♪
携帯としては自分はAndroidの方が全然良いと思っているので楽しみです♪
OSは2.2でリリースされる可能性が大なようなので、そうなるとテザリング機能がドコモにどう制御されているのかが気になる。。。
2.1以上対応のアプリをマーケットに流したけどダウンロード数がフリーアプリなのにまだ2しかない。。。あまりにもショック。。。
早く見た目まともにアップデートしよう。。。
まじですか!!
楽しみです♪
携帯としては自分はAndroidの方が全然良いと思っているので楽しみです♪
OSは2.2でリリースされる可能性が大なようなので、そうなるとテザリング機能がドコモにどう制御されているのかが気になる。。。
2.1以上対応のアプリをマーケットに流したけどダウンロード数がフリーアプリなのにまだ2しかない。。。あまりにもショック。。。
早く見た目まともにアップデートしよう。。。
2010年9月16日木曜日
2010年9月9日木曜日
第4世代iPod Touchを買ってしまった♪
iPhone4Gの白を待ってたけど、我慢できなくて。。。
これによってHT-03Aはもうちょっと長生きしてもらいます。。。
テザリングできないと意味がないんでね(;一_一)
2-3週間待ちって書いてて買って届いたメールには10月2日。。。
9月2日位に買ったんですけどね。。。
予定は未定!!果たしていつ届くのか。。。楽しみです♪
これによってHT-03Aはもうちょっと長生きしてもらいます。。。
テザリングできないと意味がないんでね(;一_一)
2-3週間待ちって書いてて買って届いたメールには10月2日。。。
9月2日位に買ったんですけどね。。。
予定は未定!!果たしていつ届くのか。。。楽しみです♪
Android Google Docs API を利用して文章を新規追加したい。。。
今回 Google Docs API を利用して。
文章(Document)の新規追加を行いたいんです。。。
一覧と編集は既に解ったのですが新規登録の方法がどうしても解らない。。。
この Google Docs API はリクエスト先のURLが自分的には特殊で解りにくいです。。。
もっと解りやすいリファレンスがあったらな。。。
URLが間違っているのか?
POSTでリクエストじゃないのか?
AtomContentの使い方が違うのか。。。
誰か教えてください。。。
文章(Document)の新規追加を行いたいんです。。。
一覧と編集は既に解ったのですが新規登録の方法がどうしても解らない。。。
この Google Docs API はリクエスト先のURLが自分的には特殊で解りにくいです。。。
もっと解りやすいリファレンスがあったらな。。。
URLが間違っているのか?
POSTでリクエストじゃないのか?
AtomContentの使い方が違うのか。。。
誰か教えてください。。。
public class Category { String scheme = "http://schemas.google.com/g/2005#kind"; String term = "http://schemas.google.com/docs/2007#document"; }
public class Entry { public Category category = new Category(); public String title; }
public void addNewDocument(String title) { showDialog(this, "Debug", "addNewDocument"); // GoogleTransportからPOSTリクエストを生成 HttpRequest request = mTransport.buildPostRequest(); // URLを生成して String url = GoogleDocumentsList.ROOT_URL + "default/private/full"; // URLをセット request.setUrl(url); // Content AtomContent content = new AtomContent(); Entry entry = new Entry(); entry.title = "newDocument"; content.entry = entry; content.namespaceDictionary = GoogleDocumentsListAtom.NAMESPACE_DICTIONARY; PlainTextContent content2 = new PlainTextContent("sample"); request.content = content2; // HttpRequestのヘッダーのifMatchに"*"をセット request.headers.ifMatch = "*"; try { // HTTPリクエストを実行! request.execute(); } catch (IOException e) { e.printStackTrace(); } }
2010年9月8日水曜日
php.ini じゃなくて 使用可能メモリー最大値を設定変更
- .htaccessファイルを利用した変更
php.ini はデフォルトのままそっとしておきたいので、今回も .htaccess で対応する事にした。
追加内容は下記
php_value memory_limit 30M
これでPHPからの利用可能メモリー最大値は30MBとなるはず。。。
- プログラム内で設定変更
ini_set('memory_limit', '30M');
でOK?
- コマンドラインの際に指定
オプション-dで対応可能みたい。
php -d memory_limit=30M foo.php
こんな感じかな。
php.ini じゃない箇所でアップファイルの容量制限変更
- htaccess ファイルを利用する。
php_value upload_max_filesize 30M
php_value post_max_size 30M
デフォルトの状態が
upload_max_filesize 2M
post_max_size 8M
これを20Mに変更する。
※Mで記述するかbyte数で記述する。
例:1KB=1024
例:1MB=1M - ini_setを利用する。
これは無理みたいです。 - コマンドラインからオプション指定
-dオプションで対応可能。
php -d upload_max_filesize=30M,post_max_size=30M foo.php
って感じかな。
2010年9月2日木曜日
モバイル広告ネットワーク プラットフォーム| AdMob
モバイル広告ネットワーク プラットフォーム| AdMob
Androidアプリによく組み込まれている広告はどうやらこれみたいですね。。。
iPhoneにも使えるみたいですが。
とりあえず無料でアプリ配布するなら入れときますか。。。
なんでAdsenseじゃないんだろう。。。って思ってたらこれGoogleに買収されてるみたいですね。
時期に統合されるんでしょうか。。。
まっとりあえず方向は間違っていないようなので、AdMobを積極的に導入していこう♪
入れ型は簡単でした。
まずはAdmobのアカウントを取得してメニュー「マーケットプレイス」からサイト及びアプリケーションの追加を選択。
なんやかんや入力して生成されたパブリッシャーIDを取得して AndroidManifest.xml のapplicationタグ内に
<meta-data android:value="[パブリッシャーID]" android:name="ADMOB_PUBLISHER_ID" />
を追加。
\admob-sdk-android\samples\LunarLander\res\values\attrs.xml ファイルを相当する場所にコピーする。
続いて広告を表示させたいページLayoutの
<meta-data android:value="[パブリッシャーID]" android:name="ADMOB_PUBLISHER_ID" />
を追加。
\admob-sdk-android\samples\LunarLander\res\values\attrs.xml ファイルを相当する場所にコピーする。
続いて広告を表示させたいページLayoutの
xmlns:android="http://schemas.android.com/apk/res/android"
の下に
xmlns:myapp="http://schemas.android.com/apk/res/com.unlax.tsurimap"
って感じで追加する。そして実際広告を表示する箇所に
android:id="@+id/ad"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
myapp:backgroundColor="#000000"
myapp:textColor="#FFFFFF"
myapp:keywords="Android application"
myapp:testing="true"
/>
て感じで追加する。
myapp:testing="true" はテスト用という意味みたいです。
本番リリース時には削除もしくはfalseにする必要があるとの事です。
2010-09-07 追記
myapp:testing="true" は古くて今は使わないみたいです。
変わりに
AdManager.setTestDevices( new String[] {
AdManager.TEST_EMULATOR, // Android emulator
"E83D20734F72FB3108F104ABC0FFC738", // My T-Mobile G1 Test Phone
});
と書くのかな?
2010年9月1日水曜日
Android
下記みたいなソースを書くと不安定になる。。。
Criteria crit = new Criteria();原因は現在不明。。。
crit.setAccuracy(Criteria.ACCURACY_FINE);
String provider = lm.getBestProvider(crit, true);
Location loc = lm.getLastKnownLocation(provider);
onLocationChanged(loc);
GeoPoint point = LocationHelper.getGeoPoint(loc);
mapController.animateTo(point);
ま~とりあえず放置で。
HT-03Aに2.1入れてるので検証してるから元から不安定。。。
エラー出た時にどっちのせいか解らないのが困る。。。
Galaxy S早く出てくれへんかな。。。
2010年8月29日日曜日
Android Xperiaのエミュレータ作成方法
Sony Ericssonで配布されているSDKをインストールしてスキンをコピーしてやればOKみたいです。
まずは書きからSDKをダウンロード
http://developer.sonyericsson.com/wportal/devworld/search-downloads/sdk?cc=gb&lc=en
このSDKをインストールするとインストールしたディレクトリの中に Xperia X10 Skin ディレクトリがあるのでそれをAndroid SDK の add-ons ディレクトリの中にコピーする。
例として自分のコピーしたパスを書くとこうなる。
C:\Program Files\Sony Ericsson\Web SDK\Xperia X10 Skin
↓
D:\Program Files\pleiades-e3.6-java-jre\android-sdk-windows\add-ons\Xperia X10 Skin
あとは、Eclipse立ち上げてAVDマネージャーから新規でエミュートする端末を作成する。
その時にターゲットにXperiaが追加されてるので、選択して完了。
まずは書きからSDKをダウンロード
http://developer.sonyericsson.com/wportal/devworld/search-downloads/sdk?cc=gb&lc=en
このSDKをインストールするとインストールしたディレクトリの中に Xperia X10 Skin ディレクトリがあるのでそれをAndroid SDK の add-ons ディレクトリの中にコピーする。
例として自分のコピーしたパスを書くとこうなる。
C:\Program Files\Sony Ericsson\Web SDK\Xperia X10 Skin
↓
D:\Program Files\pleiades-e3.6-java-jre\android-sdk-windows\add-ons\Xperia X10 Skin
あとは、Eclipse立ち上げてAVDマネージャーから新規でエミュートする端末を作成する。
その時にターゲットにXperiaが追加されてるので、選択して完了。
2010年8月25日水曜日
Android 地図をドラッグするとエラーで落ちる現象
ItemizedOverlay を利用してたら地図を移動しようとドラッグしたらアプリが落ちる現象が発生した。
原因は ItemizedOverlay の コンストラクトでした。
super( boundCenterBottom(defaultMarker) );
のみだとダメみたいです。。。
SDKのバージョンの問題もあるのかな。。。
super( boundCenterBottom(defaultMarker) );populate();
とする事で解消。
Yahho Calendar を祝日以外の指定曜日のみクリックできないようにする
Yahho Calendar
http://0-oo.net/sbox/javascript/yahho-calendar
YUIベースで作られた祝日表示対応のこのカレンダー。
祝日以外の水曜日をクリックできないようにする方法をやってみた。
まずクリックできないようにする方法が用意されているのかがポイントだけど、それは用意された。
よかった(笑)
renderBodyCellRestricted
を利用するみたい。
var cal = new YAHOO.widget.Calendar(place, config);
cal.addRenderer("8/25", cal.renderBodyCellRestricted);
こんな感じで使うみたい。
それで結局追加したのが、
yahho-calendar.js ファイルの最後に
を追加した。
で、見て解る通りrenderBodyCellRestrictedだけじゃない。。。
そうなんです、実行するタイミングが悪いのかしてrenderBodyCellRestrictedが思うように動かない。。。
で、無理やりjquery使ってclassいじっちゃいました。。。
ここまでするならrenderBodyCellRestricted無しの方がいいかも位ですね。。。
とりあえずこいつを gcalendar-holidays.js ファイルの GCalHolidays.decode 関数の最後の
のところに
って感じで追加しました。
http://0-oo.net/sbox/javascript/yahho-calendar
YUIベースで作られた祝日表示対応のこのカレンダー。
祝日以外の水曜日をクリックできないようにする方法をやってみた。
まずクリックできないようにする方法が用意されているのかがポイントだけど、それは用意された。
よかった(笑)
renderBodyCellRestricted
を利用するみたい。
var cal = new YAHOO.widget.Calendar(place, config);
cal.addRenderer("8/25", cal.renderBodyCellRestricted);
こんな感じで使うみたい。
それで結局追加したのが、
yahho-calendar.js ファイルの最後に
YahhoCal.setDisableDays = function(index) { $(".wd3").each(function(){ if (!$(this).hasClass("holiday" + index)) { var value = $(this).children("a").text(); $(this).children("a").remove(); $(this).text(value); $(this).removeClass("selectable"); $(this).addClass("restricted"); // これだけでいけるはずだけどうまく動かない。。。 var date = YahhoCal._cal.getDateByCellId($(this).attr("id")); var month = date.getMonth() + 1; var day = date.getDate(); YahhoCal._cal.addRenderer(month + "/" + day, YahhoCal._cal.renderBodyCellRestricted); } }); }
を追加した。
で、見て解る通りrenderBodyCellRestrictedだけじゃない。。。
そうなんです、実行するタイミングが悪いのかしてrenderBodyCellRestrictedが思うように動かない。。。
で、無理やりjquery使ってclassいじっちゃいました。。。
ここまでするならrenderBodyCellRestricted無しの方がいいかも位ですね。。。
とりあえずこいつを gcalendar-holidays.js ファイルの GCalHolidays.decode 関数の最後の
//コールバック
this._userCallback(days, index);
のところに
//コールバック
this._userCallback(days, index);
YahhoCal.setDisableDays(index);
って感じで追加しました。
2010年7月30日金曜日
PostgreSQL TEXT型からINTEGER型に変換する方法
そのままだとエラーだったけどキャストしたらいけた。
ALTER TABLE [table] ALTER COLUMN [column] TYPE INTEGER USING ( [column]::INTEGER );
ALTER TABLE [table] ALTER COLUMN [column] TYPE INTEGER USING ( [column]::INTEGER );
2010年7月28日水曜日
Linux コマンドで7日以上経過しているファイルを削除する
cd で対象となるディレクトリに移動してから書きコマンドを実行する。
7日以上経過しているファイルがこれで削除されるはず。
find . -type f -mtime +7 -print -exec rm -f {} \;
7日以上経過しているファイルがこれで削除されるはず。
2010年7月27日火曜日
Androidアプリ開発 設定画面を作ってみた
Androidの設定画面は設定画面用のActivityが用意されていてそれを使うようだ。
最初うまくいかなかったけど、公式サイトから下記ソースを手に入れてやってみたら何故か動いた。。。
開発中もこういった同じ事をやってるはずなのに何回かやってるうちに動いたという事は結構ある。。。
Eclipseの問題かな。。。
慣れないなこのエディタ~
最初うまくいかなかったけど、公式サイトから下記ソースを手に入れてやってみたら何故か動いた。。。
開発中もこういった同じ事をやってるはずなのに何回かやってるうちに動いたという事は結構ある。。。
Eclipseの問題かな。。。
慣れないなこのエディタ~
layoutディレクトリの中にこいつを入れてPreferenceActivityを継承したクラスから上記のLayout XMLファイルを呼び出すだけ。こんな感じ。xmlns:android="http://schemas.android.com/apk/res/android" android:key="first_preferencescreen"> android:key="wifi enabled" android:title="WiFi" /> android:key="second_preferencescreen" android:title="WiFi settings"> android:key="prefer wifi" android:title="Prefer WiFi" /> ... other preferences here ...
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Config extends PreferenceActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.config);
}
}
Androidアプリ開発 設定画面を作ってみた
Androidの設定画面は設定画面用のActivityが用意されていてそれを使うようだ。
最初うまくいかなかったけど、公式サイトから下記ソースを手に入れてやってみたら何故か動いた。。。
開発中もこういった同じ事をやってるはずなのに何回かやってるうちに動いたという事は結構ある。。。
Eclipseの問題かな。。。
慣れないなこのエディタ~
最初うまくいかなかったけど、公式サイトから下記ソースを手に入れてやってみたら何故か動いた。。。
開発中もこういった同じ事をやってるはずなのに何回かやってるうちに動いたという事は結構ある。。。
Eclipseの問題かな。。。
慣れないなこのエディタ~
layoutディレクトリの中にこいつを入れてPreferenceActivityを継承したクラスから上記のLayout XMLファイルを呼び出すだけ。こんな感じ。
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="first_preferencescreen">
android:key="wifi enabled"
android:title="WiFi" />
android:key="second_preferencescreen"
android:title="WiFi settings">
android:key="prefer wifi"
android:title="Prefer WiFi" />
... other preferences here ...
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Config extends PreferenceActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.config);
}
}
2010年7月22日木曜日
Zend_Filter の StringTrimで全角スペースを指定するとうまく動作しない
class Zend_Filter_StringTrim
にある
protected function _unicodeTrim($value, $charlist = '\\\\s')
というメソッドがあるんですが、問題はココ
return preg_replace("/$pattern/sSD", '', $value);
これはPHPでUTF-8で動作させている場合に発生する現象らしいのですが、対処方法は
return preg_replace("/$pattern/sSDu", '', $value);
と、パターン修飾子に「u」を追加してあげるだけ。
メソッドにエンコードを指定するのが用意されてるのかと思ったけでそうでもないようですね。。。
にある
protected function _unicodeTrim($value, $charlist = '\\\\s')
というメソッドがあるんですが、問題はココ
return preg_replace("/$pattern/sSD", '', $value);
これはPHPでUTF-8で動作させている場合に発生する現象らしいのですが、対処方法は
return preg_replace("/$pattern/sSDu", '', $value);
と、パターン修飾子に「u」を追加してあげるだけ。
メソッドにエンコードを指定するのが用意されてるのかと思ったけでそうでもないようですね。。。
Androidアプリ開発 始めてみた感想
やっとAndroidアプリ開発のやる気が続きはじめました!!
今までどれだけ挫折した事やら。。。(笑)
まずはマップ表示!!
よーしよし!!
バイブル見ながらで楽勝ですよ(笑)
続いてメニューを出して。。。
よーしよし!!
なかなかスムーズですね(笑)
続いてそのメニューから検索用ウィンドウへ遷移して。。。
で、躓いた。。。Intentって何?Activityって何?
ところがようやく時間が解決してくれました(笑)
気分転換は大切です(笑)
連休挟んでやってみたらなんかできました♪
今はその検索ウィンドウで検索条件を入力するフォームを作成してます。
プルダウンにセットする配列にキーを持たせるのに苦労。。。
頼みのバイブルにも書かれてない。。。
ハッシュとか無いの?オブジェクトでするの?
XMLに勝手に属性付けたらいいの?
謎。。。謎。。。
まだまだ道のりは長そうですが、頑張って完成させますよ(笑)
今までどれだけ挫折した事やら。。。(笑)
まずはマップ表示!!
よーしよし!!
バイブル見ながらで楽勝ですよ(笑)
続いてメニューを出して。。。
よーしよし!!
なかなかスムーズですね(笑)
続いてそのメニューから検索用ウィンドウへ遷移して。。。
で、躓いた。。。Intentって何?Activityって何?
ところがようやく時間が解決してくれました(笑)
気分転換は大切です(笑)
連休挟んでやってみたらなんかできました♪
今はその検索ウィンドウで検索条件を入力するフォームを作成してます。
プルダウンにセットする配列にキーを持たせるのに苦労。。。
頼みのバイブルにも書かれてない。。。
ハッシュとか無いの?オブジェクトでするの?
XMLに勝手に属性付けたらいいの?
謎。。。謎。。。
まだまだ道のりは長そうですが、頑張って完成させますよ(笑)
2010年7月9日金曜日
アプリ作ろうと本買ってしまった!
最近Androidアプリを作ろうかなって思って勉強してました。
前に買った本はVer1.6の時に出た本で、ま~大丈夫かなって思ってたけどSDKなんかのバージョンがアップされててエミュレーターの起動方法も変わってて良く解らないので、立ち読みに行ってきました。
どうせまたバージョンアップしたら買いなおしになるだろうから。。。
それにまた挫折するかもだし。。。
で立ち読みしてたら凄く良い本に出会った♪
Android2.1プログラミングバイブル
思わず買ってしまった。。。
買うつもりじゃなかったのに。。。。あ~~~~~
ま~とりあえずこの本のおかげでHelloWorldはクリアできました(笑)
今はPCに接続しての実機デバッグの方法を勉強し終わったところです。
本の通り進んでも端から忘れていきそうなので、何か組み合わせて作ってみようと思います。
体で覚えないと覚えられないタイプなので。。。
何作ろう。。。
前に買った本はVer1.6の時に出た本で、ま~大丈夫かなって思ってたけどSDKなんかのバージョンがアップされててエミュレーターの起動方法も変わってて良く解らないので、立ち読みに行ってきました。
どうせまたバージョンアップしたら買いなおしになるだろうから。。。
それにまた挫折するかもだし。。。
で立ち読みしてたら凄く良い本に出会った♪
Android2.1プログラミングバイブル
思わず買ってしまった。。。
買うつもりじゃなかったのに。。。。あ~~~~~
ま~とりあえずこの本のおかげでHelloWorldはクリアできました(笑)
今はPCに接続しての実機デバッグの方法を勉強し終わったところです。
本の通り進んでも端から忘れていきそうなので、何か組み合わせて作ってみようと思います。
体で覚えないと覚えられないタイプなので。。。
何作ろう。。。
2010年6月25日金曜日
iPhone4を買った人が会社にいたので見せてもらった。
iPhone4を買った人が会社にいたので見せてもらった。
いいな。。。
触ってみてもOSは3GSと一緒だからあまり違いが解らない。。。
実感できたのはストロボライトがあるという事位かな?
とりあえず自分は白が良いので待つけどね。。。
ケースどんなんにしようかな~
いいな。。。
触ってみてもOSは3GSと一緒だからあまり違いが解らない。。。
実感できたのはストロボライトがあるという事位かな?
とりあえず自分は白が良いので待つけどね。。。
ケースどんなんにしようかな~
2010年6月24日木曜日
DROID X 発表
前から噂にあったモトローラーの新機種がこれでしょうか?
もっと高スペックだったような。。。
http://www.itmedia.co.jp/news/articles/1006/24/news020.html
- OS
Android 2.1
※夏後半Android 2.2にアップデート予定(Flash Player 10.1対応) - CPU
1GHzプロセッサ - カメラ
720p HD動画を撮影できるデュアルフラッシュ付きの800万画素カメラ - 画面サイズ
4.3インチのタッチスクリーン(854×480ピクセル) - 本体サイズ
65.50×127.50×9.90mm - 重さ
155グラム - 内部ストレージ
8Gバイトストレージを内蔵 - 通信企画
CDMA 800/1900, EVDO rev. A、Wi-Fi(802.11n) - モバイルホットスポット機能
- バッテリー
連続待ち受け時間: 最大220時間。 - 外部接続
DLNAおよびHDMI接続対応 - 付属品
microSCカード(16GB)
2010年6月7日月曜日
本日iPhoneHD発表か!?
時差はあるので遅い時間とはなるがとうとうApple主催の新作発表会であるワールドワイドデベロッパカンファレンス(世界開発者会議、以下WWDC)が開催される♪
発表されるのはほぼ確実なんだろうけど問題は日本でいつ発売されるかかな。。。
さすがにそこまでは公開されないのだろうか。。。
楽しみです♪
発表されるのはほぼ確実なんだろうけど問題は日本でいつ発売されるかかな。。。
さすがにそこまでは公開されないのだろうか。。。
楽しみです♪
2010年5月24日月曜日
Eye-fi + Android HT-03A(ワイヤレステザリング) を試してみた。
Eye-Fi X2 Pro を買ったので、早速Pocket Wi-Fiなど色々試してみた。
まず Pocket Wi-Fi だけどやっぱりエリアが非常に問題となる。
電話と違って圏外じゃなければOKという問題でもなく、画像がアップロードされる間安定したスピードが確保できるエリアが必要となる。
最近のデジカメは画素数が高くなっているので、容量大きいですからね。。。
さっそく海にPocketWi-Fiと持って行ったけど圏外でした。。。
しかも田舎の方だと圏内でもジオタグが取得できない地域もあるようです。
エリアの問題があったので、次に考えたのはAndroid携帯でのテザリングでの連携。
最高スピードでは劣るかもしれませんが、安定度はE-Mobileより全然良いのでトータルで早くなりました。
しかしEye-Fiのジオタグ機能は一切利用できないようです。。。
しかも容量制限にもあっちゅ~まです。。。
ちなみに料金の方はちゃんとパケ放題内でした(笑)
次はEye-Fi Serverアプリでの連携を試してみます。
まず Pocket Wi-Fi だけどやっぱりエリアが非常に問題となる。
電話と違って圏外じゃなければOKという問題でもなく、画像がアップロードされる間安定したスピードが確保できるエリアが必要となる。
最近のデジカメは画素数が高くなっているので、容量大きいですからね。。。
さっそく海にPocketWi-Fiと持って行ったけど圏外でした。。。
しかも田舎の方だと圏内でもジオタグが取得できない地域もあるようです。
エリアの問題があったので、次に考えたのはAndroid携帯でのテザリングでの連携。
最高スピードでは劣るかもしれませんが、安定度はE-Mobileより全然良いのでトータルで早くなりました。
しかしEye-Fiのジオタグ機能は一切利用できないようです。。。
しかも容量制限にもあっちゅ~まです。。。
ちなみに料金の方はちゃんとパケ放題内でした(笑)
次はEye-Fi Serverアプリでの連携を試してみます。
2010年5月18日火曜日
ドコモから微妙なものが。。。
http://www.nttdocomo.co.jp/product/foma/smart_phone/sh10b/index.html
ドコモ映像無しかよ。。。
ソフトバンクはiPhoneHDの発表も無かったな。。。
てか秋にドコモから発売予定の
「サムスン製 Android搭載スマートフォン「Galaxy S」をベースとした機種を、秋に発売予定 」
がめちゃ気になる♪
それと モバイル無線ルーター も気になる。。。
PocketWi-fi どうしよう。。。
あっドコモ映像あった。
これ見ると孫氏の方が話すの上手いな~って思うな。
てかすぐ止まるぞこの映像。。。
ドコモ映像無しかよ。。。
ソフトバンクはiPhoneHDの発表も無かったな。。。
てか秋にドコモから発売予定の
「サムスン製 Android搭載スマートフォン「Galaxy S」をベースとした機種を、秋に発売予定 」
がめちゃ気になる♪
それと モバイル無線ルーター も気になる。。。
PocketWi-fi どうしよう。。。
あっドコモ映像あった。
これ見ると孫氏の方が話すの上手いな~って思うな。
てかすぐ止まるぞこの映像。。。
2010年5月17日月曜日
Android 2.2は凄いようだ。。。
なんかAndroid2.2凄い事になってますね。。。
まず速度はNexus Oneで計測したら5倍速くなったとか(@@;
凄いね~ てかなんで今まで5倍遅かったんや。。。
あと、テザリングがデフォルトOKになるようです。
でもこれなんか日本の場合はキャリアがまた制限を設けてきそうですね。。。
※テザリング…携帯をルーター化してPCとか他の機器からテザリング機種を通してインターネットする事。既にテザリングアプリなどもマーケットに出ているから驚く事でも無いけどグレーな領域だったので、デフォルトになる事でどうなるのやら。。。
あとやっぱりこういう時に基準になるNexus One!! ほしいな。。。
やっぱりAndroid端末買うならHTCなんかな。。。
まず速度はNexus Oneで計測したら5倍速くなったとか(@@;
凄いね~ てかなんで今まで5倍遅かったんや。。。
あと、テザリングがデフォルトOKになるようです。
でもこれなんか日本の場合はキャリアがまた制限を設けてきそうですね。。。
※テザリング…携帯をルーター化してPCとか他の機器からテザリング機種を通してインターネットする事。既にテザリングアプリなどもマーケットに出ているから驚く事でも無いけどグレーな領域だったので、デフォルトになる事でどうなるのやら。。。
あとやっぱりこういう時に基準になるNexus One!! ほしいな。。。
やっぱりAndroid端末買うならHTCなんかな。。。
2010年5月14日金曜日
Eye-FiカードとAndroid携帯の連携
Eye-FiカードとAndroid携帯の連携動画を見つけたので紹介。
残念ながらこのアプリには画像を編集する機能は無いようなので、画像にサインを入れたりはできません。。。
ま~ 他のアプリを探せば見つかるかもしれませんね。
これアドホック接続対応じゃないEye-Fiカードなような気がしますね。。。
アドホック接続も必要無いのかな。。。
残念ながらこのアプリには画像を編集する機能は無いようなので、画像にサインを入れたりはできません。。。
ま~ 他のアプリを探せば見つかるかもしれませんね。
これアドホック接続対応じゃないEye-Fiカードなような気がしますね。。。
アドホック接続も必要無いのかな。。。
2010年5月11日火曜日
2010年4月28日水曜日
Android携帯を選ぶ時のポイント
今年から日本で発売されているAndroid機種にも選択肢が生まれ、そろそろAndroid携帯を買いたいけどどれを選んで良いのか解らないって思う人が出てくるだろう。
という事で自分が去年から使っていて気付いた点をまとめてみた。
という事で自分が去年から使っていて気付いた点をまとめてみた。
- OSのバージョン
現在は1.0系と2.0系の両方の商品が出回っている。
DoCoMoから発売されているXperiaは1.6でSoftbankからのDesireは2.1だ。
これは正直言って2.1の方が便利。何が便利かというと具体的には2点です。- 1点目はマルチアカウント対応。
こちらは自分にとっては必須機能である。。。何故かというと現在自分はGoogleAppsを利用ているのですが、このGoogleAppsでのアカウントではマップアプリでマイマップが使えないのです。。。
なので、マップの時はGmailアカウントを利用しています。つまりGoogleAppsアカウントの利用を考えている人はマルチアカウント対応じゃないと利用できない機能があるという事です。 - 2点目はマルチタッチ
これは残念ながらあまり必要性は感じていません。。。
もちろんあれば便利なんですが、必ずしも必要があるとも思えせんね。。。
今後は対応していないと利用できないアプリも出てくるでしょうから、あと1年後には必須になっているかもしれませんが。。。
- 1点目はマルチアカウント対応。
- ディスプレイ(画面)のサイズ
4.0インチを目安に購入する事をお勧めします。基本的にはソフトウェアキーボードという画面上に表示されるキーボードで入力するのですが、これが画面が大きい方が入力しやすいです。昔より今は電話するよりメールする方が多いので、そのメールの操作がしやすい画面が大きい方が時代には合ってると思います。
あとYoutubeなんかの動画やマンガや小説なんかの書籍を見る事もこれからは普通になってくると思うので、やっぱり画面は大きい方が良いです。
ちなみにデメリットとしては消費電力が多いので、電池の寿命が。。。ですが、これは別にこれだけの問題ではないので予備バッテリーはスマートフォンでは必須です。 - メーカー
現在一番優位なのはHTCというメーカーだと思います。HTCは世界で販売端末数が多い事やそのアメリカでも多くの機種が発売されているので、非公式な情報が多いです。アメリカ人は好奇心を持った人が多いんですかね~w
ドコモから去年出たHT-03Aは情報が多いのでめちゃくちゃできますw
自分も今は中身を2.0系のROMに入れ替えて楽しんでます♪ - キャリア
現在は圧倒的にドコモが有利ですね。。。
2010年にはLTEという新しい通信企画にもドコモは参入しているので、12月位には何か出るのかもしれませんね。DELLから公開されているサンダーという機種もLTE版が来年出るそうです。LTEの特徴は通信速度100Mbpsと光並の速度となっているのでKDDI(AU)が絡んでるWiMaxより早いようです。ソフトバンクは何をやろうとしてるのか知らないですが、iPhoneは次にどの規格を想定してるんでしょうね。。。 - その他
CPUは現在1Ghzあたりで並んでます。あとはメモリーですね。。。
自分的にはRAMが多い方が良い気がしますが、ROMもやっぱり必要ですね。
何しろこれは多い方が良いですw
それより自分はカメラの性能やその他のハードが気になります。
カメラに手ぶれ補正はあるのか?
ストロボライトはあるのか?
Felica対応なのか?(今のところ無いです。。。)
ラジオ対応なのか?(必要ないですが。。。)
あとは。。。
Flash対応か?別に今のところは無くてもいいんですがね。。。
これはOS2.1以上ならこれからは対応させてくるでしょう。
メールとか日本語入力が。。。とかいう記事を見ますがAndroidはiPhoneと違ってそこらへんのアプリも自分で入れる事ができちゃうので、あまり気にする必要は無いかと思います。
2010年4月27日火曜日
遂に発売HTC Desire♪
今日が発売日ですね♪
周りに買う予定な人はいないので残念ですが。。。
まずは画面フィルムの売れ行きからチェックですかね(笑)
Xperiaより売れるのか売れないのか。。。
ちなみにAmazonで買う人へ。
下記の商品は出品者がAmazonじゃないので送料なようです。。。
周りに買う予定な人はいないので残念ですが。。。
まずは画面フィルムの売れ行きからチェックですかね(笑)
Xperiaより売れるのか売れないのか。。。
ちなみにAmazonで買う人へ。
下記の商品は出品者がAmazonじゃないので送料なようです。。。
2010年4月23日金曜日
DELL のAndroid端末、その名は「Thunder」
DELLのAndroid端末の写真を発見しました。
http://japanese.engadget.com/2010/04/21/android-thunder/
注目なのはLTE版が来年に出るというところですね(@@
ドコモはLTEを進めているので、来年にこのDELLのLTE端末を出してくる確率高くないでしょうか?
ま~DELL以外からもLTE版が出るでしょうし。解らないですが、少なくてもLTE版のAndroid端末が来年には存在する事はこれでほぼ確定でしょうし来年が楽しみになってきました♪
こんなオシャレタイプも出るみたいですね。。。
http://japanese.engadget.com/2010/04/22/flash/
そしてこんなタブレットPC型もあるんですね。。。
http://japanese.engadget.com/2010/04/22/5-streak-android-2-1/
あっ これもDELL。。。ようけ出すんですね。。。
http://japanese.engadget.com/2010/04/22/qwerty-android-smoke/
http://japanese.engadget.com/2010/04/21/android-thunder/
注目なのはLTE版が来年に出るというところですね(@@
ドコモはLTEを進めているので、来年にこのDELLのLTE端末を出してくる確率高くないでしょうか?
ま~DELL以外からもLTE版が出るでしょうし。解らないですが、少なくてもLTE版のAndroid端末が来年には存在する事はこれでほぼ確定でしょうし来年が楽しみになってきました♪
こんなオシャレタイプも出るみたいですね。。。
http://japanese.engadget.com/2010/04/22/flash/
そしてこんなタブレットPC型もあるんですね。。。
http://japanese.engadget.com/2010/04/22/5-streak-android-2-1/
あっ これもDELL。。。ようけ出すんですね。。。
http://japanese.engadget.com/2010/04/22/qwerty-android-smoke/
2010年4月22日木曜日
添付メールを送信する際のヘッダー順について
sendmailコマンドから送信する際にヘッダー情報の出力順に悩まされたのでメモ。
添付メールを送信する際にはFromよりもToよりもSubjectよりも後の必要があるみたい。
でもContent-Typeよりは前にする必要がある?
添付メールが無ければ別にFromなどより前でContent-Typeを出力しても大丈夫だった。
もっと正確な順番が決められているんだろうな。。。
添付メールを送信する際にはFromよりもToよりもSubjectよりも後の必要があるみたい。
でもContent-Typeよりは前にする必要がある?
添付メールが無ければ別にFromなどより前でContent-Typeを出力しても大丈夫だった。
もっと正確な順番が決められているんだろうな。。。
2010年4月16日金曜日
Android 2.1搭載 のAndroid携帯 HTC DROID Incredible
HTCから更に新しいが出ますね~。
カメラも800万画素で1CPUはSnapdragon 1GHzプロセッサ。
スペックはま~どうでもよくて気になるのはまたHTCかって事ですね。
やっぱりAndroid携帯はHTCの一人勝ち状態っぽいですね。
HTCだったらROMも多そうだしな。。。
やっぱりAndroidを買うならHTCなのかな。。。
日本メーカーもっと頑張ってほしいな。。。
テストケース生成ツールの PICT を利用してみた
PICTはMicrosoftから出ているアプリなようで生成方法はAll-Pair法というもの。
PICTはコマンドラインから実行するちょっととっつきにくい感じなようなので、PictMasterというExcelマクロを利用して実際は生成する事にした。
まずは PICT 本体の入手。
http://www.pairwise.org/
ここの Available Tools というリンクをクリックして、
からダウンロードした。
その後 Pict Master を
http://sourceforge.jp/projects/pictmaster/
マニュアルが含まれているので、あとはそのマニュアルに沿って利用するだけ。
水準の区切り方が気に入らないけどめちゃくちゃ使いやすいです♪
もっと早く使っておけばよかった。。。
PICTはコマンドラインから実行するちょっととっつきにくい感じなようなので、PictMasterというExcelマクロを利用して実際は生成する事にした。
まずは PICT 本体の入手。
http://www.pairwise.org/
ここの Available Tools というリンクをクリックして、
20. | PICT | Microsoft | Command-line, free |
その後 Pict Master を
http://sourceforge.jp/projects/pictmaster/
マニュアルが含まれているので、あとはそのマニュアルに沿って利用するだけ。
水準の区切り方が気に入らないけどめちゃくちゃ使いやすいです♪
もっと早く使っておけばよかった。。。
今だ人気なXperia
ドコモからの次のAndroid端末はXperia mini という噂もあるせいか、Xperiaの人気はまだまだあるようですね。。。
今週の水曜日にヨドバシカメラ梅田店に問い合わせたら、予約の受付もやっておらず週末に数台入荷するが、何台入荷するか解らないため朝から来てもらうしか無いとの事でした♪
もちろん行く気は無いんですがw
写真はXperiaとXperia mini を比較しているところ。
こんな小さいのいらないだろう。。。
HT-03Aで小さいのには懲りたよ。。。
今週の水曜日にヨドバシカメラ梅田店に問い合わせたら、予約の受付もやっておらず週末に数台入荷するが、何台入荷するか解らないため朝から来てもらうしか無いとの事でした♪
もちろん行く気は無いんですがw
写真はXperiaとXperia mini を比較しているところ。
こんな小さいのいらないだろう。。。
HT-03Aで小さいのには懲りたよ。。。
2010年4月15日木曜日
PHP PEAR::MDB2 の問題点
実は結構有名なのかこれ(?)って感じなのですが、システムのテスト中にいつもさくさくっと動いていた箇所で突如エラーが出ました。。。
あれ?何で?って事でログを調べてみると。
2010-04-15 18:24:45 JSTERROR: 準備された文 "mdb2_statement_pgsql_346f901ff5a29904456a4af1572e6465" はすでに存在します
こんなエラーログが。。。
これをヒントに調べていると下記事例を発見しました。
http://cocky.exblog.jp/7914642/
しかし、問題は今回発生したページはとてもprepareを100回以上もやっているようなところではないという事。。。
というか番号ってある?
今のMDB2には無いの?
ってそれより確率アップじゃ。。。
設定の問題かな。。。
とりあえずMDB2を修正して使う気は無いので利用するのはやめておこう。。。
今度はPDOという事で。。。
あれ?何で?って事でログを調べてみると。
2010-04-15 18:24:45 JSTERROR: 準備された文 "mdb2_statement_pgsql_346f901ff5a29904456a4af1572e6465" はすでに存在します
こんなエラーログが。。。
これをヒントに調べていると下記事例を発見しました。
http://cocky.exblog.jp/7914642/
しかし、問題は今回発生したページはとてもprepareを100回以上もやっているようなところではないという事。。。
というか番号ってある?
今のMDB2には無いの?
ってそれより確率アップじゃ。。。
設定の問題かな。。。
とりあえずMDB2を修正して使う気は無いので利用するのはやめておこう。。。
今度はPDOという事で。。。
2010年4月12日月曜日
SuperEclair v3.0 [BETA]を入れてみた
早いという噂だったので、「SuperEclair v3.0 [BETA]」を入れてみた。
というか今使ってる「Eclear2.1」が動画を見れない不具合があったので、嫌気がさしていた。。。
でも自分はGoogleAppsアカウントを利用しているので、マルチアカウント対応じゃないとMapなどがフル機能で利用できない。。。
なんて色々あって入れてみた。
ダウンロードはこちらから
http://forum.xda-developers.com/showthread.php?t=654937
※もし無理なら下記からチャンジしてみは?
http://www.4shared.com/file/4CMUyXrs/SuperEclair_v30BETA.html
結果動画が見れた!!
やった♪ Eclear系のROMだと見れないんだと勝手にルール付けしていたので、嬉しかった(笑)
や~よかったよかった♪
これで当分また自分がXperiaを買う事は無くなったかな。。。
Appsアカウントにマイマップが対応してくれてら即買うのにな。。。
ちなみに「HelixLauncher」というアプリを入れると更に高速で動作するようです。
というか今使ってる「Eclear2.1」が動画を見れない不具合があったので、嫌気がさしていた。。。
でも自分はGoogleAppsアカウントを利用しているので、マルチアカウント対応じゃないとMapなどがフル機能で利用できない。。。
なんて色々あって入れてみた。
ダウンロードはこちらから
http://forum.xda-developers.com/showthread.php?t=654937
※もし無理なら下記からチャンジしてみは?
http://www.4shared.com/file/4CMUyXrs/SuperEclair_v30BETA.html
結果動画が見れた!!
やった♪ Eclear系のROMだと見れないんだと勝手にルール付けしていたので、嬉しかった(笑)
や~よかったよかった♪
これで当分また自分がXperiaを買う事は無くなったかな。。。
Appsアカウントにマイマップが対応してくれてら即買うのにな。。。
ちなみに「HelixLauncher」というアプリを入れると更に高速で動作するようです。
DoCoMoの場合のAPN設定値
結構メモし忘れてリカバリーしちゃうのでここにメモ
契約者毎に設定が違うわけでもなく共通なようですからね。
・mopera U(Biz・ホーダイ)
APN : mpr2.bizho.net
ユーザ名 : none
MMSC : none
MCC : 440
MNC : 10
上記以外は<未設定>
* ”mopera U設定”
APN : 0120.mopera.ne.jp
その他は「mopera U(Biz・ホーダイ)」と同様
契約者毎に設定が違うわけでもなく共通なようですからね。
・mopera U(Biz・ホーダイ)
APN : mpr2.bizho.net
ユーザ名 : none
MMSC : none
MCC : 440
MNC : 10
上記以外は<未設定>
* ”mopera U設定”
APN : 0120.mopera.ne.jp
その他は「mopera U(Biz・ホーダイ)」と同様
2010年4月11日日曜日
PHP + Apache(Windows) chmodは使わないのベスト
Windows環境でのApache+PHPを利用している場合に「chmod」を利用してファイル権限を変更しようとするとファイルが読み取り専用になってしまう。
具体的には下記のように記述をするとファイルが読み取り専用となってしまった。
今回はWindowsを開発環境としていたため、本番ではLinuxで動くので問題無いっちゃ~問題ない。
でも気持ち悪いのでchmodを使用する際には下記のようにした。
具体的には下記のように記述をするとファイルが読み取り専用となってしまった。
今回はWindowsを開発環境としていたため、本番ではLinuxで動くので問題無いっちゃ~問題ない。
@chmod($filepath, 0777);
でも気持ち悪いのでchmodを使用する際には下記のようにした。
if (PHP_OS != "WIN32" && PHP_OS != "WINNT") {
@chmod($filepath, 0777);
}
相変わらず人気な「Documents To Go 2.0 Main App」
タイトル: Documents To Go 2.0 Main App
パッケージ名: com.dataviz.docstogo
MicrosoftのExcelやWord、PowerPointなどのファイルをAndroid携帯で確認したい時なんかに以前おすすめしたこのアプリ、有料の方は他のアプリと比べてお高いが、フリーでも見るだけなら十分かな?
GoogleもオンラインでOffice関連提供してるんだしアプリ出してくれればな。。。
もちろん無料でw
パッケージ名: com.dataviz.docstogo
MicrosoftのExcelやWord、PowerPointなどのファイルをAndroid携帯で確認したい時なんかに以前おすすめしたこのアプリ、有料の方は他のアプリと比べてお高いが、フリーでも見るだけなら十分かな?
GoogleもオンラインでOffice関連提供してるんだしアプリ出してくれればな。。。
もちろん無料でw
Zend_Db_Adapter_Pdo_Odbc 不具合修正しました。
昨日更新した内容では「':シングルクォート」のエスケープ処理が間違っていたので、そこらへんを修正。
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Db
* @subpackage Adapter
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*
*/
/**
* Zend_Db_Adapter_Pdo_Abstract
*/
require_once 'Zend/Db/Adapter/Pdo/Abstract.php';
/**
* Class for connecting to ODBC System databases and performing common operations.
*
* @category Zend
* @package Zend_Db
* @subpackage Adapter
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Default_Plugin_Zend_Db_Adapter_Pdo_Odbc extends Zend_Db_Adapter_Pdo_Abstract
{
/**
* PDO type.
*
* @var string
*/
protected $_pdoType = 'odbc';
protected $_rowCount;
/**
* Keys are UPPERCASE SQL datatypes or the constants
* Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
*
* Values are:
* 0 = 32-bit integer
* 1 = 64-bit integer
* 2 = float or decimal
*
* @var array Associative array of datatypes to values 0, 1, or 2.
*/
protected $_numericDataTypes = array(
Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
'INT' => Zend_Db::INT_TYPE,
'SMALLINT' => Zend_Db::INT_TYPE,
'TINYINT' => Zend_Db::INT_TYPE,
'BIGINT' => Zend_Db::BIGINT_TYPE,
'DECIMAL' => Zend_Db::FLOAT_TYPE,
'FLOAT' => Zend_Db::FLOAT_TYPE,
'MONEY' => Zend_Db::FLOAT_TYPE,
'NUMERIC' => Zend_Db::FLOAT_TYPE,
'REAL' => Zend_Db::FLOAT_TYPE,
'SMALLMONEY' => Zend_Db::FLOAT_TYPE
);
/**
* Creates a PDO DSN for the adapter from $this->_config settings.
*
* @return string
*/
protected function _dsn()
{
// baseline of DSN parts
$dsn = $this->_config;
// don't pass the username and password in the DSN
unset($dsn['username']);
unset($dsn['password']);
unset($dsn['driver_options']);
unset($dsn['port']);
// this driver supports multiple DSN prefixes
// @see http://www.php.net/manual/en/ref.pdo-dblib.connection.php
if (isset($dsn['pdoType'])) {
switch (strtolower($dsn['pdoType'])) {
default:
$this->_pdoType = 'odbc';
break;
}
unset($dsn['pdoType']);
}
if (isset($dsn['dbname'])) {
$dsn = $this->_pdoType . ':' . $dsn['dbname'];
} else {
// use all remaining parts in the DSN
foreach ($dsn as $key => $val) {
$dsn[$key] = "$key=$val";
}
$dsn = $this->_pdoType . ':' . implode(';', $dsn);
}
return $dsn;
}
/**
* @return void
*/
protected function _connect()
{
if ($this->_connection) {
return;
}
parent::_connect();
$this->_connection->exec('SET QUOTED_IDENTIFIER ON');
}
/**
* Begin a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _beginTransaction()
{
$this->_connect();
$this->_connection->exec('BEGIN TRANSACTION');
return true;
}
/**
* Commit a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _commit()
{
$this->_connect();
$this->_connection->exec('COMMIT TRANSACTION');
return true;
}
/**
* Roll-back a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _rollBack() {
$this->_connect();
$this->_connection->exec('ROLLBACK TRANSACTION');
return true;
}
/**
* Returns a list of the tables in the database.
*
* @return array
*/
public function listTables()
{
$sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
return $this->fetchCol($sql);
}
/**
* Returns the column descriptions for a table.
*
* The return value is an associative array keyed by the column name,
* as returned by the RDBMS.
*
* The value of each array element is an associative array
* with the following keys:
*
* SCHEMA_NAME => string; name of database or schema
* TABLE_NAME => string;
* COLUMN_NAME => string; column name
* COLUMN_POSITION => number; ordinal position of column in table
* DATA_TYPE => string; SQL datatype name of column
* DEFAULT => string; default expression of column, null if none
* NULLABLE => boolean; true if column can have nulls
* LENGTH => number; length of CHAR/VARCHAR
* SCALE => number; scale of NUMERIC/DECIMAL
* PRECISION => number; precision of NUMERIC/DECIMAL
* UNSIGNED => boolean; unsigned property of an integer type
* PRIMARY => boolean; true if column is part of the primary key
* PRIMARY_POSITION => integer; position of column in primary key
* PRIMARY_AUTO => integer; position of auto-generated column in primary key
*
* @todo Discover column primary key position.
* @todo Discover integer unsigned property.
*
* @param string $tableName
* @param string $schemaName OPTIONAL
* @return array
*/
public function describeTable($tableName, $schemaName = null)
{
if ($schemaName != null) {
if (strpos($schemaName, '.') !== false) {
$result = explode('.', $schemaName);
$schemaName = $result[1];
}
}
/**
* Discover metadata information about this table.
*/
$sql = "exec sp_columns @table_name = " . $this->quoteIdentifier($tableName, true);
if ($schemaName != null) {
$sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true);
}
$stmt = $this->query($sql);
$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
$stmt->closeCursor();
$table_name = 2;
$column_name = 3;
$type_name = 5;
$precision = 6;
$length = 7;
$scale = 8;
$nullable = 10;
$column_def = 12;
$column_position = 16;
/**
* Discover primary key column(s) for this table.
*/
$sql = "exec sp_pkeys @table_name = " . $this->quoteIdentifier($tableName, true);
if ($schemaName != null) {
$sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true);
}
$stmt = $this->query($sql);
$primaryKeysResult = $stmt->fetchAll(Zend_Db::FETCH_NUM);
$stmt->closeCursor();
$pkey_column_name = 3;
$pkey_key_seq = 4;
foreach ($primaryKeysResult as $pkeysRow) {
$primaryKeyColumn[$pkeysRow[$pkey_column_name]] = $pkeysRow[$pkey_key_seq];
}
$desc = array();
$p = 1;
foreach ($result as $key => $row) {
$identity = false;
$words = explode(' ', $row[$type_name], 2);
if (isset($words[0])) {
$type = $words[0];
if (isset($words[1])) {
$identity = (bool) preg_match('/identity/', $words[1]);
}
}
$isPrimary = array_key_exists($row[$column_name], $primaryKeyColumn);
if ($isPrimary) {
$primaryPosition = $primaryKeyColumn[$row[$column_name]];
} else {
$primaryPosition = null;
}
$desc[$this->foldCase($row[$column_name])] = array(
'SCHEMA_NAME' => null, // @todo
'TABLE_NAME' => $this->foldCase($row[$table_name]),
'COLUMN_NAME' => $this->foldCase($row[$column_name]),
'COLUMN_POSITION' => (int) $row[$column_position],
'DATA_TYPE' => $type,
'DEFAULT' => $row[$column_def],
'NULLABLE' => (bool) $row[$nullable],
'LENGTH' => $row[$length],
'SCALE' => $row[$scale],
'PRECISION' => $row[$precision],
'UNSIGNED' => null, // @todo
'PRIMARY' => $isPrimary,
'PRIMARY_POSITION' => $primaryPosition,
'IDENTITY' => $identity
);
}
return $desc;
}
/**
* Adds an adapter-specific LIMIT clause to the SELECT statement.
*
* @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
*
* @param string $sql
* @param integer $count
* @param integer $offset OPTIONAL
* @return string
*/
public function limit($sql, $count, $offset = 0)
{
$count = intval($count);
if ($count <= 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
}
$offset = intval($offset);
if ($offset < 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
}
$sql = preg_replace(
'/^SELECT\s+(DISTINCT\s)?/i',
'SELECT $1TOP ' . ($count+$offset) . ' ',
$sql
);
if ($offset > 0) {
$orderby = stristr($sql, 'ORDER BY');
if ($orderby !== false) {
$orderParts = explode(',', substr($orderby, 8));
$pregReplaceCount = null;
$orderbyInverseParts = array();
foreach ($orderParts as $orderPart) {
$orderPart = rtrim($orderPart);
$inv = preg_replace('/\s+desc$/i', ' ASC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
$orderbyInverseParts[] = $inv;
continue;
}
$inv = preg_replace('/\s+asc$/i', ' DESC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
$orderbyInverseParts[] = $inv;
continue;
} else {
$orderbyInverseParts[] = $orderPart . ' DESC';
}
}
$orderbyInverse = 'ORDER BY ' . implode(', ', $orderbyInverseParts);
}
if (!is_null($this->getRowCount()) && ($count+$offset) > $this->getRowCount())
$count = $this->getRowCount() - $offset;
$sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl';
if ($orderby !== false) {
$sql .= ' ' . $orderbyInverse . ' ';
}
$sql .= ') AS outer_tbl';
if ($orderby !== false) {
$sql .= ' ' . $orderby;
}
}
return $sql;
}
/**
* Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
*
* As a convention, on RDBMS brands that support sequences
* (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
* from the arguments and returns the last id generated by that sequence.
* On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
* returns the last value generated for such a column, and the table name
* argument is disregarded.
*
* Microsoft SQL Server does not support sequences, so the arguments to
* this method are ignored.
*
* @param string $tableName OPTIONAL Name of table.
* @param string $primaryKey OPTIONAL Name of primary key column.
* @return string
* @throws Zend_Db_Adapter_Exception
*/
public function lastInsertId($tableName = null, $primaryKey = null)
{
$sql = 'SELECT SCOPE_IDENTITY()';
return (int)$this->fetchOne($sql);
}
public function getServerVersion()
{
try {
$stmt = $this->query("SELECT SERVERPROPERTY('productversion')");
$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
if (count($result)) {
return $result[0][0];
}
return null;
} catch (PDOException $e) {
return null;
}
}
protected function _quote($value)
{
if (is_int($value)) {
return $value;
} elseif (is_float($value)) {
return sprintf('%F', $value);
}
/*
* Original
* return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
*/
$value = str_replace("'", "''", $value);
return "'" . addcslashes($value, "\000\n\r\032") . "'";
}
public function getRowCount()
{
return $this->_rowCount;
}
public function setRowCount($count)
{
$this->_rowCount = $count;
}
}
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Db
* @subpackage Adapter
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*
*/
/**
* Zend_Db_Adapter_Pdo_Abstract
*/
require_once 'Zend/Db/Adapter/Pdo/Abstract.php';
/**
* Class for connecting to ODBC System databases and performing common operations.
*
* @category Zend
* @package Zend_Db
* @subpackage Adapter
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Default_Plugin_Zend_Db_Adapter_Pdo_Odbc extends Zend_Db_Adapter_Pdo_Abstract
{
/**
* PDO type.
*
* @var string
*/
protected $_pdoType = 'odbc';
protected $_rowCount;
/**
* Keys are UPPERCASE SQL datatypes or the constants
* Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
*
* Values are:
* 0 = 32-bit integer
* 1 = 64-bit integer
* 2 = float or decimal
*
* @var array Associative array of datatypes to values 0, 1, or 2.
*/
protected $_numericDataTypes = array(
Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
'INT' => Zend_Db::INT_TYPE,
'SMALLINT' => Zend_Db::INT_TYPE,
'TINYINT' => Zend_Db::INT_TYPE,
'BIGINT' => Zend_Db::BIGINT_TYPE,
'DECIMAL' => Zend_Db::FLOAT_TYPE,
'FLOAT' => Zend_Db::FLOAT_TYPE,
'MONEY' => Zend_Db::FLOAT_TYPE,
'NUMERIC' => Zend_Db::FLOAT_TYPE,
'REAL' => Zend_Db::FLOAT_TYPE,
'SMALLMONEY' => Zend_Db::FLOAT_TYPE
);
/**
* Creates a PDO DSN for the adapter from $this->_config settings.
*
* @return string
*/
protected function _dsn()
{
// baseline of DSN parts
$dsn = $this->_config;
// don't pass the username and password in the DSN
unset($dsn['username']);
unset($dsn['password']);
unset($dsn['driver_options']);
unset($dsn['port']);
// this driver supports multiple DSN prefixes
// @see http://www.php.net/manual/en/ref.pdo-dblib.connection.php
if (isset($dsn['pdoType'])) {
switch (strtolower($dsn['pdoType'])) {
default:
$this->_pdoType = 'odbc';
break;
}
unset($dsn['pdoType']);
}
if (isset($dsn['dbname'])) {
$dsn = $this->_pdoType . ':' . $dsn['dbname'];
} else {
// use all remaining parts in the DSN
foreach ($dsn as $key => $val) {
$dsn[$key] = "$key=$val";
}
$dsn = $this->_pdoType . ':' . implode(';', $dsn);
}
return $dsn;
}
/**
* @return void
*/
protected function _connect()
{
if ($this->_connection) {
return;
}
parent::_connect();
$this->_connection->exec('SET QUOTED_IDENTIFIER ON');
}
/**
* Begin a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _beginTransaction()
{
$this->_connect();
$this->_connection->exec('BEGIN TRANSACTION');
return true;
}
/**
* Commit a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _commit()
{
$this->_connect();
$this->_connection->exec('COMMIT TRANSACTION');
return true;
}
/**
* Roll-back a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _rollBack() {
$this->_connect();
$this->_connection->exec('ROLLBACK TRANSACTION');
return true;
}
/**
* Returns a list of the tables in the database.
*
* @return array
*/
public function listTables()
{
$sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
return $this->fetchCol($sql);
}
/**
* Returns the column descriptions for a table.
*
* The return value is an associative array keyed by the column name,
* as returned by the RDBMS.
*
* The value of each array element is an associative array
* with the following keys:
*
* SCHEMA_NAME => string; name of database or schema
* TABLE_NAME => string;
* COLUMN_NAME => string; column name
* COLUMN_POSITION => number; ordinal position of column in table
* DATA_TYPE => string; SQL datatype name of column
* DEFAULT => string; default expression of column, null if none
* NULLABLE => boolean; true if column can have nulls
* LENGTH => number; length of CHAR/VARCHAR
* SCALE => number; scale of NUMERIC/DECIMAL
* PRECISION => number; precision of NUMERIC/DECIMAL
* UNSIGNED => boolean; unsigned property of an integer type
* PRIMARY => boolean; true if column is part of the primary key
* PRIMARY_POSITION => integer; position of column in primary key
* PRIMARY_AUTO => integer; position of auto-generated column in primary key
*
* @todo Discover column primary key position.
* @todo Discover integer unsigned property.
*
* @param string $tableName
* @param string $schemaName OPTIONAL
* @return array
*/
public function describeTable($tableName, $schemaName = null)
{
if ($schemaName != null) {
if (strpos($schemaName, '.') !== false) {
$result = explode('.', $schemaName);
$schemaName = $result[1];
}
}
/**
* Discover metadata information about this table.
*/
$sql = "exec sp_columns @table_name = " . $this->quoteIdentifier($tableName, true);
if ($schemaName != null) {
$sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true);
}
$stmt = $this->query($sql);
$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
$stmt->closeCursor();
$table_name = 2;
$column_name = 3;
$type_name = 5;
$precision = 6;
$length = 7;
$scale = 8;
$nullable = 10;
$column_def = 12;
$column_position = 16;
/**
* Discover primary key column(s) for this table.
*/
$sql = "exec sp_pkeys @table_name = " . $this->quoteIdentifier($tableName, true);
if ($schemaName != null) {
$sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true);
}
$stmt = $this->query($sql);
$primaryKeysResult = $stmt->fetchAll(Zend_Db::FETCH_NUM);
$stmt->closeCursor();
$pkey_column_name = 3;
$pkey_key_seq = 4;
foreach ($primaryKeysResult as $pkeysRow) {
$primaryKeyColumn[$pkeysRow[$pkey_column_name]] = $pkeysRow[$pkey_key_seq];
}
$desc = array();
$p = 1;
foreach ($result as $key => $row) {
$identity = false;
$words = explode(' ', $row[$type_name], 2);
if (isset($words[0])) {
$type = $words[0];
if (isset($words[1])) {
$identity = (bool) preg_match('/identity/', $words[1]);
}
}
$isPrimary = array_key_exists($row[$column_name], $primaryKeyColumn);
if ($isPrimary) {
$primaryPosition = $primaryKeyColumn[$row[$column_name]];
} else {
$primaryPosition = null;
}
$desc[$this->foldCase($row[$column_name])] = array(
'SCHEMA_NAME' => null, // @todo
'TABLE_NAME' => $this->foldCase($row[$table_name]),
'COLUMN_NAME' => $this->foldCase($row[$column_name]),
'COLUMN_POSITION' => (int) $row[$column_position],
'DATA_TYPE' => $type,
'DEFAULT' => $row[$column_def],
'NULLABLE' => (bool) $row[$nullable],
'LENGTH' => $row[$length],
'SCALE' => $row[$scale],
'PRECISION' => $row[$precision],
'UNSIGNED' => null, // @todo
'PRIMARY' => $isPrimary,
'PRIMARY_POSITION' => $primaryPosition,
'IDENTITY' => $identity
);
}
return $desc;
}
/**
* Adds an adapter-specific LIMIT clause to the SELECT statement.
*
* @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
*
* @param string $sql
* @param integer $count
* @param integer $offset OPTIONAL
* @return string
*/
public function limit($sql, $count, $offset = 0)
{
$count = intval($count);
if ($count <= 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
}
$offset = intval($offset);
if ($offset < 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
}
$sql = preg_replace(
'/^SELECT\s+(DISTINCT\s)?/i',
'SELECT $1TOP ' . ($count+$offset) . ' ',
$sql
);
if ($offset > 0) {
$orderby = stristr($sql, 'ORDER BY');
if ($orderby !== false) {
$orderParts = explode(',', substr($orderby, 8));
$pregReplaceCount = null;
$orderbyInverseParts = array();
foreach ($orderParts as $orderPart) {
$orderPart = rtrim($orderPart);
$inv = preg_replace('/\s+desc$/i', ' ASC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
$orderbyInverseParts[] = $inv;
continue;
}
$inv = preg_replace('/\s+asc$/i', ' DESC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
$orderbyInverseParts[] = $inv;
continue;
} else {
$orderbyInverseParts[] = $orderPart . ' DESC';
}
}
$orderbyInverse = 'ORDER BY ' . implode(', ', $orderbyInverseParts);
}
if (!is_null($this->getRowCount()) && ($count+$offset) > $this->getRowCount())
$count = $this->getRowCount() - $offset;
$sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl';
if ($orderby !== false) {
$sql .= ' ' . $orderbyInverse . ' ';
}
$sql .= ') AS outer_tbl';
if ($orderby !== false) {
$sql .= ' ' . $orderby;
}
}
return $sql;
}
/**
* Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
*
* As a convention, on RDBMS brands that support sequences
* (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
* from the arguments and returns the last id generated by that sequence.
* On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
* returns the last value generated for such a column, and the table name
* argument is disregarded.
*
* Microsoft SQL Server does not support sequences, so the arguments to
* this method are ignored.
*
* @param string $tableName OPTIONAL Name of table.
* @param string $primaryKey OPTIONAL Name of primary key column.
* @return string
* @throws Zend_Db_Adapter_Exception
*/
public function lastInsertId($tableName = null, $primaryKey = null)
{
$sql = 'SELECT SCOPE_IDENTITY()';
return (int)$this->fetchOne($sql);
}
public function getServerVersion()
{
try {
$stmt = $this->query("SELECT SERVERPROPERTY('productversion')");
$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
if (count($result)) {
return $result[0][0];
}
return null;
} catch (PDOException $e) {
return null;
}
}
protected function _quote($value)
{
if (is_int($value)) {
return $value;
} elseif (is_float($value)) {
return sprintf('%F', $value);
}
/*
* Original
* return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
*/
$value = str_replace("'", "''", $value);
return "'" . addcslashes($value, "\000\n\r\032") . "'";
}
public function getRowCount()
{
return $this->_rowCount;
}
public function setRowCount($count)
{
$this->_rowCount = $count;
}
}
ラベル:
IIS,
PHP,
ZendFramework
2010年4月10日土曜日
Zend_Db_Adapter_Pdo_Odbc 不具合修正しました。
quoteをオーバーライドしているところで問題があったのを修正。
っていうか addslashes に第2パラメーターが存在したとは。。。
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Db
* @subpackage Adapter
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*
*/
/**
* Zend_Db_Adapter_Pdo_Abstract
*/
require_once 'Zend/Db/Adapter/Pdo/Abstract.php';
/**
* Class for connecting to ODBC System databases and performing common operations.
*
* @category Zend
* @package Zend_Db
* @subpackage Adapter
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Db_Adapter_Pdo_Odbc extends Zend_Db_Adapter_Pdo_Abstract
{
/**
* PDO type.
*
* @var string
*/
protected $_pdoType = 'odbc';
protected $_rowCount;
/**
* Keys are UPPERCASE SQL datatypes or the constants
* Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
*
* Values are:
* 0 = 32-bit integer
* 1 = 64-bit integer
* 2 = float or decimal
*
* @var array Associative array of datatypes to values 0, 1, or 2.
*/
protected $_numericDataTypes = array(
Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
'INT' => Zend_Db::INT_TYPE,
'SMALLINT' => Zend_Db::INT_TYPE,
'TINYINT' => Zend_Db::INT_TYPE,
'BIGINT' => Zend_Db::BIGINT_TYPE,
'DECIMAL' => Zend_Db::FLOAT_TYPE,
'FLOAT' => Zend_Db::FLOAT_TYPE,
'MONEY' => Zend_Db::FLOAT_TYPE,
'NUMERIC' => Zend_Db::FLOAT_TYPE,
'REAL' => Zend_Db::FLOAT_TYPE,
'SMALLMONEY' => Zend_Db::FLOAT_TYPE
);
/**
* Creates a PDO DSN for the adapter from $this->_config settings.
*
* @return string
*/
protected function _dsn()
{
// baseline of DSN parts
$dsn = $this->_config;
// don't pass the username and password in the DSN
unset($dsn['username']);
unset($dsn['password']);
unset($dsn['driver_options']);
unset($dsn['port']);
// this driver supports multiple DSN prefixes
// @see http://www.php.net/manual/en/ref.pdo-dblib.connection.php
if (isset($dsn['pdoType'])) {
switch (strtolower($dsn['pdoType'])) {
default:
$this->_pdoType = 'odbc';
break;
}
unset($dsn['pdoType']);
}
if (isset($dsn['dbname'])) {
$dsn = $this->_pdoType . ':' . $dsn['dbname'];
} else {
// use all remaining parts in the DSN
foreach ($dsn as $key => $val) {
$dsn[$key] = "$key=$val";
}
$dsn = $this->_pdoType . ':' . implode(';', $dsn);
}
return $dsn;
}
/**
* @return void
*/
protected function _connect()
{
if ($this->_connection) {
return;
}
parent::_connect();
$this->_connection->exec('SET QUOTED_IDENTIFIER ON');
}
/**
* Begin a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _beginTransaction()
{
$this->_connect();
$this->_connection->exec('BEGIN TRANSACTION');
return true;
}
/**
* Commit a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _commit()
{
$this->_connect();
$this->_connection->exec('COMMIT TRANSACTION');
return true;
}
/**
* Roll-back a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _rollBack() {
$this->_connect();
$this->_connection->exec('ROLLBACK TRANSACTION');
return true;
}
/**
* Returns a list of the tables in the database.
*
* @return array
*/
public function listTables()
{
$sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
return $this->fetchCol($sql);
}
/**
* Returns the column descriptions for a table.
*
* The return value is an associative array keyed by the column name,
* as returned by the RDBMS.
*
* The value of each array element is an associative array
* with the following keys:
*
* SCHEMA_NAME => string; name of database or schema
* TABLE_NAME => string;
* COLUMN_NAME => string; column name
* COLUMN_POSITION => number; ordinal position of column in table
* DATA_TYPE => string; SQL datatype name of column
* DEFAULT => string; default expression of column, null if none
* NULLABLE => boolean; true if column can have nulls
* LENGTH => number; length of CHAR/VARCHAR
* SCALE => number; scale of NUMERIC/DECIMAL
* PRECISION => number; precision of NUMERIC/DECIMAL
* UNSIGNED => boolean; unsigned property of an integer type
* PRIMARY => boolean; true if column is part of the primary key
* PRIMARY_POSITION => integer; position of column in primary key
* PRIMARY_AUTO => integer; position of auto-generated column in primary key
*
* @todo Discover column primary key position.
* @todo Discover integer unsigned property.
*
* @param string $tableName
* @param string $schemaName OPTIONAL
* @return array
*/
public function describeTable($tableName, $schemaName = null)
{
if ($schemaName != null) {
if (strpos($schemaName, '.') !== false) {
$result = explode('.', $schemaName);
$schemaName = $result[1];
}
}
/**
* Discover metadata information about this table.
*/
$sql = "exec sp_columns @table_name = " . $this->quoteIdentifier($tableName, true);
if ($schemaName != null) {
$sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true);
}
$stmt = $this->query($sql);
$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
$stmt->closeCursor();
$table_name = 2;
$column_name = 3;
$type_name = 5;
$precision = 6;
$length = 7;
$scale = 8;
$nullable = 10;
$column_def = 12;
$column_position = 16;
/**
* Discover primary key column(s) for this table.
*/
$sql = "exec sp_pkeys @table_name = " . $this->quoteIdentifier($tableName, true);
if ($schemaName != null) {
$sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true);
}
$stmt = $this->query($sql);
$primaryKeysResult = $stmt->fetchAll(Zend_Db::FETCH_NUM);
$stmt->closeCursor();
$pkey_column_name = 3;
$pkey_key_seq = 4;
foreach ($primaryKeysResult as $pkeysRow) {
$primaryKeyColumn[$pkeysRow[$pkey_column_name]] = $pkeysRow[$pkey_key_seq];
}
$desc = array();
$p = 1;
foreach ($result as $key => $row) {
$identity = false;
$words = explode(' ', $row[$type_name], 2);
if (isset($words[0])) {
$type = $words[0];
if (isset($words[1])) {
$identity = (bool) preg_match('/identity/', $words[1]);
}
}
$isPrimary = array_key_exists($row[$column_name], $primaryKeyColumn);
if ($isPrimary) {
$primaryPosition = $primaryKeyColumn[$row[$column_name]];
} else {
$primaryPosition = null;
}
$desc[$this->foldCase($row[$column_name])] = array(
'SCHEMA_NAME' => null, // @todo
'TABLE_NAME' => $this->foldCase($row[$table_name]),
'COLUMN_NAME' => $this->foldCase($row[$column_name]),
'COLUMN_POSITION' => (int) $row[$column_position],
'DATA_TYPE' => $type,
'DEFAULT' => $row[$column_def],
'NULLABLE' => (bool) $row[$nullable],
'LENGTH' => $row[$length],
'SCALE' => $row[$scale],
'PRECISION' => $row[$precision],
'UNSIGNED' => null, // @todo
'PRIMARY' => $isPrimary,
'PRIMARY_POSITION' => $primaryPosition,
'IDENTITY' => $identity
);
}
return $desc;
}
/**
* Adds an adapter-specific LIMIT clause to the SELECT statement.
*
* @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
*
* @param string $sql
* @param integer $count
* @param integer $offset OPTIONAL
* @return string
*/
public function limit($sql, $count, $offset = 0)
{
$count = intval($count);
if ($count <= 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
}
$offset = intval($offset);
if ($offset < 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
}
$sql = preg_replace(
'/^SELECT\s+(DISTINCT\s)?/i',
'SELECT $1TOP ' . ($count+$offset) . ' ',
$sql
);
if ($offset > 0) {
$orderby = stristr($sql, 'ORDER BY');
if ($orderby !== false) {
$orderParts = explode(',', substr($orderby, 8));
$pregReplaceCount = null;
$orderbyInverseParts = array();
foreach ($orderParts as $orderPart) {
$orderPart = rtrim($orderPart);
$inv = preg_replace('/\s+desc$/i', ' ASC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
$orderbyInverseParts[] = $inv;
continue;
}
$inv = preg_replace('/\s+asc$/i', ' DESC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
$orderbyInverseParts[] = $inv;
continue;
} else {
$orderbyInverseParts[] = $orderPart . ' DESC';
}
}
$orderbyInverse = 'ORDER BY ' . implode(', ', $orderbyInverseParts);
}
if (!is_null($this->getRowCount()) && ($count+$offset) > $this->getRowCount())
$count = $this->getRowCount() - $offset;
$sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl';
if ($orderby !== false) {
$sql .= ' ' . $orderbyInverse . ' ';
}
$sql .= ') AS outer_tbl';
if ($orderby !== false) {
$sql .= ' ' . $orderby;
}
}
return $sql;
}
/**
* Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
*
* As a convention, on RDBMS brands that support sequences
* (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
* from the arguments and returns the last id generated by that sequence.
* On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
* returns the last value generated for such a column, and the table name
* argument is disregarded.
*
* Microsoft SQL Server does not support sequences, so the arguments to
* this method are ignored.
*
* @param string $tableName OPTIONAL Name of table.
* @param string $primaryKey OPTIONAL Name of primary key column.
* @return string
* @throws Zend_Db_Adapter_Exception
*/
public function lastInsertId($tableName = null, $primaryKey = null)
{
$sql = 'SELECT SCOPE_IDENTITY()';
return (int)$this->fetchOne($sql);
}
public function getServerVersion()
{
try {
$stmt = $this->query("SELECT SERVERPROPERTY('productversion')");
$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
if (count($result)) {
return $result[0][0];
}
return null;
} catch (PDOException $e) {
return null;
}
}
protected function _quote($value)
{
if (is_int($value)) {
return $value;
} elseif (is_float($value)) {
return sprintf('%F', $value);
}
/*
* Original
* return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
*/
return "'" . addcslashes($value, "\000\n\r'\"\032") . "'";
}
public function getRowCount()
{
return $this->_rowCount;
}
public function setRowCount($count)
{
$this->_rowCount = $count;
}
}
っていうか addslashes に第2パラメーターが存在したとは。。。
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Db
* @subpackage Adapter
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*
*/
/**
* Zend_Db_Adapter_Pdo_Abstract
*/
require_once 'Zend/Db/Adapter/Pdo/Abstract.php';
/**
* Class for connecting to ODBC System databases and performing common operations.
*
* @category Zend
* @package Zend_Db
* @subpackage Adapter
* @copyright Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Db_Adapter_Pdo_Odbc extends Zend_Db_Adapter_Pdo_Abstract
{
/**
* PDO type.
*
* @var string
*/
protected $_pdoType = 'odbc';
protected $_rowCount;
/**
* Keys are UPPERCASE SQL datatypes or the constants
* Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
*
* Values are:
* 0 = 32-bit integer
* 1 = 64-bit integer
* 2 = float or decimal
*
* @var array Associative array of datatypes to values 0, 1, or 2.
*/
protected $_numericDataTypes = array(
Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
'INT' => Zend_Db::INT_TYPE,
'SMALLINT' => Zend_Db::INT_TYPE,
'TINYINT' => Zend_Db::INT_TYPE,
'BIGINT' => Zend_Db::BIGINT_TYPE,
'DECIMAL' => Zend_Db::FLOAT_TYPE,
'FLOAT' => Zend_Db::FLOAT_TYPE,
'MONEY' => Zend_Db::FLOAT_TYPE,
'NUMERIC' => Zend_Db::FLOAT_TYPE,
'REAL' => Zend_Db::FLOAT_TYPE,
'SMALLMONEY' => Zend_Db::FLOAT_TYPE
);
/**
* Creates a PDO DSN for the adapter from $this->_config settings.
*
* @return string
*/
protected function _dsn()
{
// baseline of DSN parts
$dsn = $this->_config;
// don't pass the username and password in the DSN
unset($dsn['username']);
unset($dsn['password']);
unset($dsn['driver_options']);
unset($dsn['port']);
// this driver supports multiple DSN prefixes
// @see http://www.php.net/manual/en/ref.pdo-dblib.connection.php
if (isset($dsn['pdoType'])) {
switch (strtolower($dsn['pdoType'])) {
default:
$this->_pdoType = 'odbc';
break;
}
unset($dsn['pdoType']);
}
if (isset($dsn['dbname'])) {
$dsn = $this->_pdoType . ':' . $dsn['dbname'];
} else {
// use all remaining parts in the DSN
foreach ($dsn as $key => $val) {
$dsn[$key] = "$key=$val";
}
$dsn = $this->_pdoType . ':' . implode(';', $dsn);
}
return $dsn;
}
/**
* @return void
*/
protected function _connect()
{
if ($this->_connection) {
return;
}
parent::_connect();
$this->_connection->exec('SET QUOTED_IDENTIFIER ON');
}
/**
* Begin a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _beginTransaction()
{
$this->_connect();
$this->_connection->exec('BEGIN TRANSACTION');
return true;
}
/**
* Commit a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _commit()
{
$this->_connect();
$this->_connection->exec('COMMIT TRANSACTION');
return true;
}
/**
* Roll-back a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*/
protected function _rollBack() {
$this->_connect();
$this->_connection->exec('ROLLBACK TRANSACTION');
return true;
}
/**
* Returns a list of the tables in the database.
*
* @return array
*/
public function listTables()
{
$sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
return $this->fetchCol($sql);
}
/**
* Returns the column descriptions for a table.
*
* The return value is an associative array keyed by the column name,
* as returned by the RDBMS.
*
* The value of each array element is an associative array
* with the following keys:
*
* SCHEMA_NAME => string; name of database or schema
* TABLE_NAME => string;
* COLUMN_NAME => string; column name
* COLUMN_POSITION => number; ordinal position of column in table
* DATA_TYPE => string; SQL datatype name of column
* DEFAULT => string; default expression of column, null if none
* NULLABLE => boolean; true if column can have nulls
* LENGTH => number; length of CHAR/VARCHAR
* SCALE => number; scale of NUMERIC/DECIMAL
* PRECISION => number; precision of NUMERIC/DECIMAL
* UNSIGNED => boolean; unsigned property of an integer type
* PRIMARY => boolean; true if column is part of the primary key
* PRIMARY_POSITION => integer; position of column in primary key
* PRIMARY_AUTO => integer; position of auto-generated column in primary key
*
* @todo Discover column primary key position.
* @todo Discover integer unsigned property.
*
* @param string $tableName
* @param string $schemaName OPTIONAL
* @return array
*/
public function describeTable($tableName, $schemaName = null)
{
if ($schemaName != null) {
if (strpos($schemaName, '.') !== false) {
$result = explode('.', $schemaName);
$schemaName = $result[1];
}
}
/**
* Discover metadata information about this table.
*/
$sql = "exec sp_columns @table_name = " . $this->quoteIdentifier($tableName, true);
if ($schemaName != null) {
$sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true);
}
$stmt = $this->query($sql);
$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
$stmt->closeCursor();
$table_name = 2;
$column_name = 3;
$type_name = 5;
$precision = 6;
$length = 7;
$scale = 8;
$nullable = 10;
$column_def = 12;
$column_position = 16;
/**
* Discover primary key column(s) for this table.
*/
$sql = "exec sp_pkeys @table_name = " . $this->quoteIdentifier($tableName, true);
if ($schemaName != null) {
$sql .= ", @table_owner = " . $this->quoteIdentifier($schemaName, true);
}
$stmt = $this->query($sql);
$primaryKeysResult = $stmt->fetchAll(Zend_Db::FETCH_NUM);
$stmt->closeCursor();
$pkey_column_name = 3;
$pkey_key_seq = 4;
foreach ($primaryKeysResult as $pkeysRow) {
$primaryKeyColumn[$pkeysRow[$pkey_column_name]] = $pkeysRow[$pkey_key_seq];
}
$desc = array();
$p = 1;
foreach ($result as $key => $row) {
$identity = false;
$words = explode(' ', $row[$type_name], 2);
if (isset($words[0])) {
$type = $words[0];
if (isset($words[1])) {
$identity = (bool) preg_match('/identity/', $words[1]);
}
}
$isPrimary = array_key_exists($row[$column_name], $primaryKeyColumn);
if ($isPrimary) {
$primaryPosition = $primaryKeyColumn[$row[$column_name]];
} else {
$primaryPosition = null;
}
$desc[$this->foldCase($row[$column_name])] = array(
'SCHEMA_NAME' => null, // @todo
'TABLE_NAME' => $this->foldCase($row[$table_name]),
'COLUMN_NAME' => $this->foldCase($row[$column_name]),
'COLUMN_POSITION' => (int) $row[$column_position],
'DATA_TYPE' => $type,
'DEFAULT' => $row[$column_def],
'NULLABLE' => (bool) $row[$nullable],
'LENGTH' => $row[$length],
'SCALE' => $row[$scale],
'PRECISION' => $row[$precision],
'UNSIGNED' => null, // @todo
'PRIMARY' => $isPrimary,
'PRIMARY_POSITION' => $primaryPosition,
'IDENTITY' => $identity
);
}
return $desc;
}
/**
* Adds an adapter-specific LIMIT clause to the SELECT statement.
*
* @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html
*
* @param string $sql
* @param integer $count
* @param integer $offset OPTIONAL
* @return string
*/
public function limit($sql, $count, $offset = 0)
{
$count = intval($count);
if ($count <= 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
}
$offset = intval($offset);
if ($offset < 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
}
$sql = preg_replace(
'/^SELECT\s+(DISTINCT\s)?/i',
'SELECT $1TOP ' . ($count+$offset) . ' ',
$sql
);
if ($offset > 0) {
$orderby = stristr($sql, 'ORDER BY');
if ($orderby !== false) {
$orderParts = explode(',', substr($orderby, 8));
$pregReplaceCount = null;
$orderbyInverseParts = array();
foreach ($orderParts as $orderPart) {
$orderPart = rtrim($orderPart);
$inv = preg_replace('/\s+desc$/i', ' ASC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
$orderbyInverseParts[] = $inv;
continue;
}
$inv = preg_replace('/\s+asc$/i', ' DESC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
$orderbyInverseParts[] = $inv;
continue;
} else {
$orderbyInverseParts[] = $orderPart . ' DESC';
}
}
$orderbyInverse = 'ORDER BY ' . implode(', ', $orderbyInverseParts);
}
if (!is_null($this->getRowCount()) && ($count+$offset) > $this->getRowCount())
$count = $this->getRowCount() - $offset;
$sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl';
if ($orderby !== false) {
$sql .= ' ' . $orderbyInverse . ' ';
}
$sql .= ') AS outer_tbl';
if ($orderby !== false) {
$sql .= ' ' . $orderby;
}
}
return $sql;
}
/**
* Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column.
*
* As a convention, on RDBMS brands that support sequences
* (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence
* from the arguments and returns the last id generated by that sequence.
* On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method
* returns the last value generated for such a column, and the table name
* argument is disregarded.
*
* Microsoft SQL Server does not support sequences, so the arguments to
* this method are ignored.
*
* @param string $tableName OPTIONAL Name of table.
* @param string $primaryKey OPTIONAL Name of primary key column.
* @return string
* @throws Zend_Db_Adapter_Exception
*/
public function lastInsertId($tableName = null, $primaryKey = null)
{
$sql = 'SELECT SCOPE_IDENTITY()';
return (int)$this->fetchOne($sql);
}
public function getServerVersion()
{
try {
$stmt = $this->query("SELECT SERVERPROPERTY('productversion')");
$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
if (count($result)) {
return $result[0][0];
}
return null;
} catch (PDOException $e) {
return null;
}
}
protected function _quote($value)
{
if (is_int($value)) {
return $value;
} elseif (is_float($value)) {
return sprintf('%F', $value);
}
/*
* Original
* return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
*/
return "'" . addcslashes($value, "\000\n\r'\"\032") . "'";
}
public function getRowCount()
{
return $this->_rowCount;
}
public function setRowCount($count)
{
$this->_rowCount = $count;
}
}
登録:
投稿 (Atom)