[JavaScript]本番環境時、存在しないconsole.log()でエラーを出さない方法

firefox+firebugを使用して、javascript開発を行う際console.log()関数を使用すると、
デバッグログをコンソールに出力できるので便利です。

とても便利なconsole.log()ですが、リリース時に該当処理を削除し忘れると、コンソールの無い環境では当然エラーが出てしまいます。
このような場合は、以下のコードを入れておくと、エラーを回避できます。

if (typeof('console') == 'undefined') {
    console = { 
        log: function(){}
    };
}


これで、consoleがない場合に限り、何もしないlog()関数を作成してくれます。



この記事は、以下のページを参考に作成しました。
Hidden Features of JavaScript?

JavaScriptとC言語のスコープの違い

C言語では、ブロック内のみ有効なスコープというものが存在します。
例えば、下記のコードで、”a = 20″はブロック内のみで有効なので、”a=10″と表示されます。

int a = 10;
{
	int a = 20;
}
printf( "a=%d", a  );		// a=10が表示される。




一方でJavaScriptでは、ブロック単位でのスコープが存在しません。
この為、下記のコードでaの値は20となります。

var a = 10;
{
	var a = 20;
}
alert( "a=" + a );		// a=20が表示される。



Cプログラマがはまりやすい罠なので注意が必要です。


この記事は、以下のページを参考に作成しました。
Hidden Features of JavaScript?

[JavaScript]変数の引数を可変個にする方法

JavaScriptで可変引数に対応するには、arguments[i]を使用します。

プログラム


<script>
function sum() {
    var retval = 0;
    for (var i = 0, len = arguments.length; i < len; ++i) {
        retval += arguments[i];
    }
    return retval;
}
 
 
alert( sum(1, 2, 3) );       // 6
alert( sum(1, 2, 3, 4, 5) ); // 15
</script>



テスト



この記事は、以下のページを参考に作成しています。
Hidden Features of JavaScript?

[メモ]SICPの目次

SICP = Structure and Interpretation of Computer Programs
邦訳版のタイトルは、「計算機プログラムの構造と解釈(SICP)」



書籍は下記のサイトでCCライセンスで、全公開されている。
http://mitpress.mit.edu/sicp/full-text/book/book.html
Creative Commons Attribution-ShareAlike 3.0 Unported License.



SICP(Structure and Interpretation of Computer Programs)の目次

1  Building Abstractions with Procedures
    1.1  The Elements of Programming
        1.1.1  Expressions
        1.1.2  Naming and the Environment
        1.1.3  Evaluating Combinations
        1.1.4  Compound Procedures
        1.1.5  The Substitution Model for Procedure Application
        1.1.6  Conditional Expressions and Predicates
        1.1.7  Example: Square Roots by Newton's Method
        1.1.8  Procedures as Black-Box Abstractions
    1.2  Procedures and the Processes They Generate
        1.2.1  Linear Recursion and Iteration
        1.2.2  Tree Recursion
        1.2.3  Orders of Growth
        1.2.4  Exponentiation
        1.2.5  Greatest Common Divisors
        1.2.6  Example: Testing for Primality
    1.3  Formulating Abstractions with Higher-Order Procedures
        1.3.1  Procedures as Arguments
        1.3.2  Constructing Procedures Using Lambda
        1.3.3  Procedures as General Methods
        1.3.4  Procedures as Returned Values
 
2  Building Abstractions with Data
    2.1  Introduction to Data Abstraction
        2.1.1  Example: Arithmetic Operations for Rational Numbers
        2.1.2  Abstraction Barriers
        2.1.3  What Is Meant by Data?
        2.1.4  Extended Exercise: Interval Arithmetic
    2.2  Hierarchical Data and the Closure Property
        2.2.1  Representing Sequences
        2.2.2  Hierarchical Structures
        2.2.3  Sequences as Conventional Interfaces
        2.2.4  Example: A Picture Language
    2.3  Symbolic Data
        2.3.1  Quotation
        2.3.2  Example: Symbolic Differentiation
        2.3.3  Example: Representing Sets
        2.3.4  Example: Huffman Encoding Trees
    2.4  Multiple Representations for Abstract Data
        2.4.1  Representations for Complex Numbers
        2.4.2  Tagged data
        2.4.3  Data-Directed Programming and Additivity
    2.5  Systems with Generic Operations
        2.5.1  Generic Arithmetic Operations
        2.5.2  Combining Data of Different Types
        2.5.3  Example: Symbolic Algebra
 
3  Modularity, Objects, and State
    3.1  Assignment and Local State
        3.1.1  Local State Variables
        3.1.2  The Benefits of Introducing Assignment
        3.1.3  The Costs of Introducing Assignment
    3.2  The Environment Model of Evaluation
        3.2.1  The Rules for Evaluation
        3.2.2  Applying Simple Procedures
        3.2.3  Frames as the Repository of Local State
        3.2.4  Internal Definitions
    3.3  Modeling with Mutable Data
        3.3.1  Mutable List Structure
        3.3.2  Representing Queues
        3.3.3  Representing Tables
        3.3.4  A Simulator for Digital Circuits
        3.3.5  Propagation of Constraints
    3.4  Concurrency: Time Is of the Essence
        3.4.1  The Nature of Time in Concurrent Systems
        3.4.2  Mechanisms for Controlling Concurrency
    3.5  Streams
        3.5.1  Streams Are Delayed Lists
        3.5.2  Infinite Streams
        3.5.3  Exploiting the Stream Paradigm
        3.5.4  Streams and Delayed Evaluation
        3.5.5  Modularity of Functional Programs and Modularity of Objects
 
4  Metalinguistic Abstraction
    4.1  The Metacircular Evaluator
        4.1.1  The Core of the Evaluator
        4.1.2  Representing Expressions
        4.1.3  Evaluator Data Structures
        4.1.4  Running the Evaluator as a Program
        4.1.5  Data as Programs
        4.1.6  Internal Definitions
        4.1.7  Separating Syntactic Analysis from Execution
    4.2  Variations on a Scheme -- Lazy Evaluation
        4.2.1  Normal Order and Applicative Order
        4.2.2  An Interpreter with Lazy Evaluation
        4.2.3  Streams as Lazy Lists
    4.3  Variations on a Scheme -- Nondeterministic Computing
        4.3.1  Amb and Search
        4.3.2  Examples of Nondeterministic Programs
        4.3.3  Implementing the Amb Evaluator
    4.4  Logic Programming
        4.4.1  Deductive Information Retrieval
        4.4.2  How the Query System Works
        4.4.3  Is Logic Programming Mathematical Logic?
        4.4.4  Implementing the Query System
 
5  Computing with Register Machines
    5.1  Designing Register Machines
        5.1.1  A Language for Describing Register Machines
        5.1.2  Abstraction in Machine Design
        5.1.3  Subroutines
        5.1.4  Using a Stack to Implement Recursion
        5.1.5  Instruction Summary
    5.2  A Register-Machine Simulator
        5.2.1  The Machine Model
        5.2.2  The Assembler
        5.2.3  Generating Execution Procedures for Instructions
        5.2.4  Monitoring Machine Performance
    5.3  Storage Allocation and Garbage Collection
        5.3.1  Memory as Vectors
        5.3.2  Maintaining the Illusion of Infinite Memory
    5.4  The Explicit-Control Evaluator
        5.4.1  The Core of the Explicit-Control Evaluator
        5.4.2  Sequence Evaluation and Tail Recursion
        5.4.3  Conditionals, Assignments, and Definitions
        5.4.4  Running the Evaluator
    5.5  Compilation
        5.5.1  Structure of the Compiler
        5.5.2  Compiling Expressions
        5.5.3  Compiling Combinations
        5.5.4  Combining Instruction Sequences
        5.5.5  An Example of Compiled Code
        5.5.6  Lexical Addressing
        5.5.7  Interfacing Compiled Code to the Evaluator

[jQuery]新しいノードを追加するときに、タグの属性も同時に指定する方法

jQueryでは、$( “<a />” )という表記で新しいDOMノードを作ることが出来ます。
上記の例では、アンカータグを生成します。

この際、第二引数にハッシュを指定することで、属性(attribute)も同時に指定可能です。

例:

var newLink = $( "<a />", { href: "http://www.yahoo.co.jp/", title: "yahoo", });
newLink.text( "yahooホームページ" );
 
$( "#links" ).append( newLink );



上記の例では、以下のタグを作り,id=”links”ノードの下に追加しています。

<a href="http://www.yahoo.co.jp/" title="yahoo">yahooホームページ</a>





また、keyがcssの項目を定義することで、スタイルの指定を行うことも出来ます。
(説明の為,途中で改行しています)

var newLink = $("<a />", { href: "http://www.yahoo.co.jp/", 
                           title: "yahoo",
                           css: { color:"#F00", "background-color": "#FF0", }, });



テスト




この記事は、以下のページを参考に作成しています。
jQuery Tips and Tricks

[jQuery]指定したノードが存在するときのみ処理を行う

jQueryでは、$( “#btnShow” )といった形式で、特定のDOMノードを指定可能です。
このとき指定したノードが存在するときのみ処理を行う方法です。

プログラム

<input id="btnShow" type="button" value="表示" />
<div id="someDiv"/>message area</div>
 
<script>
$( function() { 
    $( "#btnShow" ).click( function() {
        var someDiv;
 
        // idが"someDiv"のノードがあるときのみメッセージ表示処理を実行する
        if ( ( someDiv = $("#someDiv") ).length) {
           someDiv.text( "hello world" );
        }
    });
});
</script>
 
<style>
#someDiv {
    width:200px;
    padding:10px;
    background-color:#fcc
}
</style>





テスト


message area




この記事は、以下のページを参考に作成しています。
jQuery Tips and Tricks

[jQuery] jQueryのプロパティ「$.expr」を使用して、独自のセレクタを実装する

jQueryでは、:first、:lastや:animatedなどのセレクタでDOMのノードを指定することが出来ます。
では、jQueryに標準で用意されていないセレクタが欲しくなった場合はどうすればよいでしょうか?


このような場合は、$.expr[‘:’]に対して、関数を定義することでセレクタを追加することが可能です。
下記の例では、幅が100pxを超える要素のみを抽出するセレクタ”over100pixels”を定義しています。

<script>
$.extend($.expr[':'], {
    over100pixels: function (e)
    {
        return $(e).width() > 100;
    }
});
</script>




実際にこのセレクタを利用する場合は、自作したセレクタである事を意識せずに指定することが可能です。

<script>
$(".box:over100pixels").click(function () {
    alert("幅100px以上のBOXです。");
});
</script>
<div class="box" style="width:80px" />width:80px</div>
<div class="box" style="width:90px" />width:90px</div>
<div class="box" style="width:100px" />width:100px</div>
<div class="box" style="width:110px" />width:110px</div>
<div class="box" style="width:120px" />width:120px</div>
<div class="box" style="width:130px" />width:130px</div>



テスト

下3つの要素をクリックしたときのみメッセージが表示されます。

width:80px
width:90px
width:100px
width:110px
width:120px
width:130px



この記事は、以下のページを参考に作成しています。
jQuery Tips and Tricks

[JavaScript]Shift+Enterでformをsubmitさせる方法



$('#form').keydown(function(e) {
    if( e.keyCode === 13 && e.shiftKey ) {  // When "Shift + Enter"
        // code 
    } else { 
        e.preventDefault();
    }
});



“// code”の部分でsubmit処理を行います。

また、preventDefault()は、行われたイベントのキャンセル処理です。 → 参考


本記事の元ネタは、stackoverflow.comの下記Q&Aです。
Shift+Enter button used for submitting form

[JavaScript]ハッシュのキー存在チェック関数

JavaScriptで、ハッシュ(連想配列)に指定したキーが存在するかどうかのチェック関数です。
通常の関数として使用する場合と、Arrayクラス自体に関数を追加するパターンを用意したので、お好みの方を使用してください。

プログラム


//-------------------------------------------------------------
// ハッシュのキー存在チェック(通常の関数として実装する場合)
//-------------------------------------------------------------
function array_key_exists (key, search) {
    // Checks if the given key or index exists in the array  
    // 
    // version: 1109.2015
    // discuss at: http://phpjs.org/functions/array_key_exists    
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Felix Geisendoerfer (http://www.debuggable.com/felix)
    // *     example 1: array_key_exists('kevin', {'kevin': 'van Zonneveld'});
    // *     returns 1: true
    //input sanitation    
    if (!search || (search.constructor !== Array && search.constructor !== Object)) {
        return false;
    }
 
    return key in search;
}


※コメントにもありますが、本関数はhttp://phpjs.org/functions/array_key_existsのから引用です。



//-------------------------------------------------------------
// ハッシュのキー存在チェック(Arrayクラス自体を拡張する場合)
//-------------------------------------------------------------
Array.prototype.containsKey = function( key ) {
	return key in this;
	//obj.hasOwnProperty( key ); //継承元のプロパティは見たくない場合、hasOwnProperty()を使用する
}








動作確認のプログラム

で、こちらは動作確認用のサンプルソースです

<input id="btnInput" type="button" value="表示" />
<script>
$(document).ready(function(){
 
    // 入力ボタンがクリックされたときのハンドラ
    $("#btnInput").click(function() {
    	testValue = new Array();
    	testValue[ "key1" ] = "value1";
    	testValue[ "key2" ] = "value2";
 
    	alert( "case1: key1 exist? → " + array_key_exists( "key1", testValue ) );  // true
    	alert( "case1: keyX exist? → " + array_key_exists( "keyX", testValue ) );  // false
 
    	alert( "case2: key1 exist? → " + testValue.containsKey( "key1" ) );        // true
    	alert( "case2: keyX exist? → " + testValue.containsKey( "keyX" ) );        // false
 
    });
});
</script>








補足


プログラム中のコメントにも記載しましたが、継承元のプロパティ(キー)をチェックからはずしたい場合は、inの代わりにhasOwnProperty()関数を使用します。
参考資料はこちらです。

[JavaScript]URLのパラメータをハッシュとして取得する

URLのパラメータをハッシュとして取得する関数です。
URLのパラメータというのは、”http://example.com/?key1=value1&key2=value2″というURLがあった場合、”key1=value1&key2=value2″に相当する部分です。

上記例の場合に、関数をコールすると以下の2要素を持つハッシュがリターンされます。
params[ “key1” ] = “value1”;
params[ “key2” ] = “value2”;



関数です。

//--------------------------------------------
// URLのパラメータをハッシュとして取得する
//--------------------------------------------
<script>
function getQueryString () {
    var retVal = new Array();
 
    // 「?」以降のパラメータ部を取得する
    var searchStr = window.location.search;
    if ( searchStr == "" ) {
        alert( "no params" );
        return;
    }
 
    // 各パラメータに分割する
    var params = searchStr.substring( 1 ).split( "&" );
 
    // 分割した全パラメータをハッシュに登録する
    for ( var i = 0; i < params.length; i++ ) {
        // パラメータのkey,valueを取得する
        keyValue = params[i].split( "=" );
 
        // ハッシュに値を登録する
        if ( keyValue.length == 1 ) {
            retVal[ keyValue[0] ] = "";
        } else {
            retVal[ keyValue[0] ] = keyValue[1];
        }
    }
 
    // 登録されたハッシュを返す
    return retVal;
}
</script>




関数の呼び側の例は、以下のような感じになります。

<input id="btnInput" type="button" value="表示" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>
<script>
$(document).ready(function(){
    // 入力ボタンがクリックされたときのハンドラ
    $("#btnInput").click(function() {
        params = getQueryString();
        for( var key in params ) {
            alert( "key[" + key + "] -> [" + params[key] + "]"  );
        }
    });
});
</script>


ゲーミフィケーションでよく使われるバッジをcssだけで作成する


ゲーミフィケーションを考える際、作業を行った報酬としてバッジを提供することが有ります。

例えばfoursquareやロケタッチなどの大きなサービスでは、全てのバッジを個別の画像で作成してますが、個人で作るような小さなWebサービスでは、なかなか個別の画像を用意することは出来ません。

そこで、今回はcssだけを使用して見栄えのするバッジを作ってみます。
また、デザインの分野に不慣れな人でも簡単に作ることが出来るよう、今回は作成の過程も紹介します。

今回は例として、”よくできました”の文字を装飾していくことにします。




まずは装飾無し。普通の文字です。

ソース

<a>よくできました</a>







色の指定を行います。

ソース

<a class="badge1">よくできました</a>
<style>
.badge1 {
    color: #EEE;
    background-color: #666;
    border: 1px solid #333;
}
</style>







エッジを丸くしてやわらかい印象にします。
同時に、余白の微調整を行います。

<a class="badge2">よくできました</a>
<style>
.badge2 {
    color: #EEE;
    background-color: #666;
    border: 1px solid #333;
 
    border-radius: 6px;
    display: inline-block;
    padding: 0px 6px;
    white-space: nowrap;
}
</style>







フォントを指定します。
かなり良くなってきました。

<a class="badge3">よくできました</a>
<style>
.badge3 {
    color: #EEE;
    background-color: #666;
    border: 1px solid #333;
 
    border-radius: 6px;
    display: inline-block;
    padding: 0px 6px;
    white-space: nowrap;
 
    text-decoration: none;
	font-family: Meiryo;
    margin: 5px;
}
</style>







バッジはランクを指定することが多いので、金/銀/銅の王冠アイコンをつけてみます。
まずは、画像を張ります。
まだレイアウトが変ですね。

<a class="badge3 badge-gold3">よくできました</a>
<style>
.badge3 {
    color: #EEE;
    background-color: #666;
    border: 1px solid #333;
 
    border-radius: 6px;
    display: inline-block;
    padding: 0px 6px;
    white-space: nowrap;
 
    text-decoration: none;
    font-family: Meiryo;
    margin: 5px;
}
 
.badge-gold3 {
    background-image: url("http://nanoappli.com/blog/wp-content/uploads/gold.gif");
    background-repeat: no-repeat;
}
</style>







位置の微調整を行います。
また、class定義を変えれるだけで他のアイコンも表示できるように,cssのクラス定義も増やしておきます。


<p class="badge badge-gold">よくできました</p>
<p class="badge badge-silver">よくできました</p>
<p class="badge badge-bronze">よくできました</p>
<style>
.badge {
    color: #EEE;
    background-color: #666;
    border: 1px solid #333;
    border-radius: 6px;
    display: inline-block;
    padding: 0px 6px 0 20px;
    white-space: nowrap;
    text-decoration: none;
    font-family: Meiryo;
    margin: 5px;
}
 
.badge-gold {
    background-image: url("http://nanoappli.com/blog/wp-content/uploads/gold.gif");
    background-repeat: no-repeat;
    background-position: 6px 6px;
}
.badge-silver {
    background-image: url("http://nanoappli.com/blog/wp-content/uploads/silver.gif");
    background-repeat: no-repeat;
    background-position: 6px 6px;
}
.badge-bronze {
    background-image: url("http://nanoappli.com/blog/wp-content/uploads/bronze.gif");
    background-repeat: no-repeat;
    background-position: 6px 6px;
}
</style>





今回の記事を書くに当たり、以下のサイトの素材を使用させていただきました。
http://sozai.7gates.net/

王冠の素材は以下のページよりダウンロードできます。
http://sozai.7gates.net/docs/crown-mini-icon03/

[jQuery]iframeを動的に追加して,googlemapを表示させる

htmlの中でjQueryを使用して動的にiframeをappendするサンプルです。
例では、入力された住所を元にgooglemapを表示しています。

ソース:

<input type="text"   id="txtAddress" value="東京都千代田区丸の内一丁目" size="30" />
<input type="button" id="btnTest"    value="iframe追加"/>
<div style="width:380px;height:310px;background-color:#FF9;" id="test"></div>
 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>
<script>
$( function(){
    $("#btnTest").click( function() {
        var address   = $( "#txtAddress" ).val();
        var searchKey = encodeURI( address );
        var zoom = 16;
 
        var iframeText;
        iframeText  = '<iframe width="380" height="310" ';
        iframeText +=         'frameborder="0"  scrolling="no"';
        iframeText +=         'marginheight="0" marginwidth="0"';
        iframeText +=         'src="http://maps.google.co.jp/maps?f=q&amp;source=s_q&amp;hl=ja&amp;&amp;q=' +searchKey+ '&amp;ie=UTF8&amp;z=' +zoom+ '&amp;iwloc=B&amp;output=embed">';
        iframeText += '</iframe>';
 
        $("#test").append( iframeText );
    });
});
</script>




サンプル:(ボタンクリック前の黄色い枠は、単なるdivタグです)



[WebAPI]ヤマト運輸の営業所情報を取得するAPIを作成しました

先月、ヤマト運輸の伝票状態を取得するAPIを作成したのですが、
伝票検索に続いて、営業所の検索APIも作成しました。


WebAPI


API仕様は、伝票情報取得APIの時と同じような感じです。

実際に見た方が速いと思うので、以下に各フォーマットの例を示します.(058100の部分には営業所コードが入ります)

xml/json/yaml

http://nanoappli.com/tracking/api/center/058100.xml
http://nanoappli.com/tracking/api/center/058100.json
http://nanoappli.com/tracking/api/center/058100.yaml

jsonp

http://nanoappli.com/tracking/api/center/058100/callbackFunc


返って来るデータ

例によって、xmlフォーマットだけ例示します。

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <result>0</result>
    <status />
    <centerCode>058100</centerCode>
    <centerName>大垣東前センター</centerName>
    <postalCode>503-0854</postalCode>
    <address>岐阜県大垣市築捨町3−81</address>
    <open>
        <weekday>08:00 〜 21:00</weekday>
        <saturday>08:00 〜 21:00</saturday>
        <holiday>08:00 〜 21:00</holiday>
    </open>
    <limit>
        <weekday>19:00</weekday>
        <saturday>19:00</saturday>
        <holiday>19:00</holiday>
    </limit>
    <inquiryCenterName>岐阜主管支店 サービスセンター</inquiryCenterName>
    <telNo>0575-25-6677</telNo>
    <faxNo>0575-25-6668</faxNo>
 
    <inquiryTime>8:00 〜 21:00</inquiryTime>
</root>



result, statusの扱いは伝票情報取得APIと同一仕様です。

また、openは営業時間、limitは当日集荷の期限時間です。
それぞれ、ブランクの場合や”お問い合わせ窓口にご確認ください。”といった文字列が入ることが有る点に注意してください。


取得できたデータの内容

営業所データは2012/01/20時点のものです。

現在は最新データを自動取得する処理は無くキャッシュから取得していますが、要望があれば最新データの取得ロジック(キャッシュのリフレッシュ処理)を追加します。



その他情報

営業所コードのコード体系は、こちらの記事を参照してください。

伝票Noから荷物の状態を取得する場合は -> こちら
APIではなく、画面から検索したい場合は -> こちら

SQL Server2012で追加される新しい組み込み関数14個


前回の記事では、SQL Server 2012で追加される新構文を紹介しました。

本記事では、組み込み関数でとして追加される14個の関数を説明します。
追加された関数は大きく分けると、分岐処理・日付処理・変換処理・文字列処理に分類されます。

分岐処理

  • choose
  • iif

日付処理
  • eomonth
  • datefromparts
  • datetime2fromparts
  • datetimefromparts
  • datetimeoffsetfromparts
  • smalldatetimefromparts
  • timefromparts

変換処理
  • parse
  • try_convert
  • try_parse

文字列処理
  • concat
  • format

それでは、各関数の内容を確認していきましょう。


分岐処理


choose:値の条件分け

複数の値からオフセットを指定して、値を決定します。
excelの同名関数とおなじ処理です。

SQL

SELECT choose( 2, 'AAA', 'AA+', 'AA', 'A-', 'A' )



実行結果

AA+





iif:分岐

語源:Immediate IF

条件分岐をcase句を使用せず、シンプルに表記できます。
excelの同名関数とおなじ処理です。

SQL

DECLARE @param VARCHAR(4) = '0001';
SELECT IIF( @param = '0001', 'true', 'false' );



実行結果

true





日付処理


eomonth:月末の取得

語源:End Of MONTH

eomonth()で月末を簡単に取得可能です。

SQL

SELECT eomonth( '2012/01/10' )



実行結果

2012-01-31 00:00:00.0000000





datefromparts:文字列から日付型の取得

語源:DATE FROM PARTS

年・月・日それぞれを意味する文字列から日付型データを取得できます。
他に同系統の処理として、以下の関数が追加されています。
datetime2fromparts, datetimefromparts, datetimeoffsetfromparts, smalldatetimefromparts, timefromparts

SQL

SELECT datefromparts( '2012' '01', '10' )



実行結果

2012-01-10





変換処理


try_convert:型のキャストを試みる

TRY_CONVERTは、型のキャストが出来るかチェックし、キャストできない場合はNULLを返します。
他に同様の関数として、PARSE, TRY_PARSEが追加されています。

SQL

SELECT CASE WHEN try_convert( FLOAT,'10.0A') IS NULL
             THEN 'NG'
             ELSE 'OK'
        END



実行結果

NG





文字列処理


concat:文字列の結合

語源:CONCATenate

今までのSQLServerでは”+”で文字列連結を行っていましたが、concat()で結合を行うことが出来ます。
Oracleのconcat()関数と異なり、sqlserverでは、引数を3つ以上指定可能です。

SQL

SELECT concat( 'hello', ' ', 'world' )



実行結果

hello world





こちらの記事もどうぞ:
SQLServer2012のSQLで追加される便利な新機能4つ

SQLServer2012のSQLで追加される便利な新機能4つ


2012年4月に出荷予定のSQL Server2012ではSQL文(Transact-SQL)に新しい構文が追加されます。


本記事では、SQL Server2012で新たに追加される新構文の中でも、特に便利な以下の4点を紹介します。

  • シーケンス
  • 検索結果のページング
  • EXECでプロシジャ実行時の結果セット
  • 例外処理での再スロー処理


シーケンス

データベース上でデータ一意性を確保するために、一意の連番を振りたい場合があります。
この為の機能としてシーケンスが追加されました。
シーケンスというのは、文字通り自動で連番を振る機能で、Oracleでは同じものが既に実装されています。
また、MySQLでは全く同じものではありませんが同様の機能として、AUTO_INCREMENT属性というものが有ります。


シーケンスは、CREATE SEQUENCE句を使用して、以下のSQLで事前に定義する必要があります。

CREATE SEQUENCE seq_item_id AS INT
START WITH 1
INCREMENT BY 1
MAXVALUE 10000;




実際に使用する時は、以下のように”VALUE FOR”で定義したシーケンスを指定します。

INSERT INTO ITEM_MASTER( ID ) VALUES( VALUE FOR seq_item_id );




なお、このシーケンスはトランザクションをサポートしていないため、以下のスクリプトを実行した場合でもシーケンス値は加算されることに注意が必要です。

BEGIN TRANSACTION
SELECT NEXT VALUE FOR seq_item_id;
ROLLBACK TRANSACTION





検索結果のページング

主にGUIプログラムにおいて、大量のデータを表示させる場合ページング処理を行う場合があります。
例えばgoogle検索では、のデフォルトで1ページあたり10件の検索結果を表示させ、以降のデータを見たい場合は”次ページ”をクリックさせることで、結果表示のレスポンスを向上せています。

SQLServer2012では、このページング処理を簡単に行う為にOFFEST-FETCH構文が追加されました。

SELECT *
FROM ItemMaster
ORDER BY ID
OFFSET 100 ROWS
FETCH NEXT 10 ROWS ONLY;


上記の例では、検索結果の101~110件目までの10件を取得可能です。

これはMySQLでlimit句として実装されているものと同様の機能です。


EXECでプロシジャ実行時の結果セット


SQLServer2012では、EXECステートメントでプロシジャを実行した際、プロシジャから結果セットを取得することが可能です。

例えば、以下のスクリプトをSQLServer Management Studioで実行すると、EXECの結果として結果セットが表示されます。

-- ストアドプロシジャを作成する
CREATE PROC getItemList
AS
	-- 商品マスタを返す
	SELECT id, name FROM ItemMaster;
GO
 
 
EXEC getItemList WITH RESULT SETS (
	(
		id INT,
		name VARCHAR(64)
	)
);





例外処理での再スロー処理

SQLServerのストアドプロシジャであるTransact-SQLでは、SQLServer2005以降において例外処理がサポートされています。
ただ、この例外処理はJavaやC#の様に、発生した例外ををCATCH句で再送出することが困難でした。
※厳密にはRAISEERRORで例外を再作成すれば擬似的に例外の再送出は可能でしたが、その記述は煩雑なものでした


これがSQLServer2012では、簡単に例外の再スローがTHROWの1行で可能となります。

BEGIN TRY
	BEGIN TRANSACTION
 
	SELCECT 1 / 0;   -- わざと例外を発生させる
 
	COMMIT TRANSACTION
END TRY
BEGIN CATCH
	ROLLBACK TRANSACTION
	THROW					-- THROWで、発生した例外を再送出可能
END CATCH


THROWの1行で、CATCH句で捕獲した例外を再送出できます。


こちらの記事もどうぞ:
SQL Server2012で追加される新しい組み込み関数14個

lolipopで、PHPとPDOを使用してDBに接続する

前回、PHP-MySQLを使用したプログラムで失敗したので、今回はPDOを使用してDBにアクセスします。
前回の失敗記事 -> lolipopで、PHPとPDOを使用してDBに接続する


今回使用するPDOライブラリですがですが、以下の特長を持っています。

  • PHP5以降の環境で標準インストールされているパッケージ
  • 比較的速い(各DBネイティブのAPI程ではないが)
  • MySQLに限らず、接続するDBに依存しないインターフェース(関数)


というわけで、いきなりプログラムです。

<?php
$ermsg = "";
//---------------------------------------------------
// DBに接続する
//---------------------------------------------------
function getConnection() {
    $server   = "mysqlxxx.phy.lolipop.jp";              // 実際の接続値に置き換える
    $user     = "LAxxxxxxxx";                           // 実際の接続値に置き換える
    $pass     = "xxxxxxxxxx";                           // 実際の接続値に置き換える
    $database = "LAxxxxxx-dbname";                      // 実際の接続値に置き換える
    //-------------------
    //DBに接続
    //-------------------
    $pdo = new PDO("mysql:host=" . $server . "; dbname=".$database, $user, $pass );
    return $pdo;
}
 
//---------------------------------------------------
// SQLを実行する
//---------------------------------------------------
function execute( $conn, $sql, $param = array() ) {
    //-------------------
    //クエリのセット
    //-------------------
    $stmt = $conn->prepare( $sql );
 
    //-----------------------
    // バインド変数のセット
    //-----------------------
    foreach( $param as $key => $value ) {
        //$stmt->bindValue( 1, "aaa" );   // ?でbindするとき(1 origin)
        $stmt->bindValue( $key, $value );
    }
 
    //-------------------
    //クエリの実行
    //-------------------
    $stmt->execute();
 
    return $stmt;
}
 
 
//---------------------------------------------------
// PDOテストメイン
//---------------------------------------------------
function testMain() {
    try {
        //----------------------------
        //DBへ接続する
        //----------------------------
        $conn = getConnection() ;
 
        //----------------------------
        // SQLの実行
        //----------------------------
        $sql  = <<< QUERY
            select table_name
            from   INFORMATION_SCHEMA.tables
            where  table_name like "C%"
QUERY;
        $stmt = execute( $conn, $sql );
 
 
        //----------------------------
        // 結果の出力
        //----------------------------
        echo "test case 1----------------------------------------------------\n";
        while( $row = $stmt->fetch(PDO::FETCH_ASSOC ) ) { 
            echo $row[ "table_name" ] . "\n";
        }
 
    } catch ( PDOException $ex ) {
 
        $ermsg =  $ex->getMessage();
        return null;
    }
 
    $conn = null;
}
?>
 
 
<!-- 検索結果をダンプする -->
<pre>
<?php testMain(); ?>
&gt;/pre>
 
<!-- エラー発生時のメッセージ -->
<?php echo $ermsg; ?>



上記の処理でDBアクセスが可能です。

実行結果:

test case 1----------------------------------------------------
CHARACTER_SETS
COLLATIONS
COLLATION_CHARACTER_SET_APPLICABILITY
COLUMNS
COLUMN_PRIVILEGES






また、前回ダメだったプリペアステートメントもPDOでは使用可能です。
以下のような記述で…

<?php
//---------------------------------------------------
// PDOテストメイン
//---------------------------------------------------
function testMain() {
    try {
        //----------------------------
        //DBへ接続する
        //----------------------------
        $conn = getConnection() ;
 
        //----------------------------
        // バインド変数もOK
        //----------------------------
        $sql  = <<< QUERY
            select table_name,
                    engine
            from   INFORMATION_SCHEMA.tables
            where  engine     =    :engine
            and    table_name like :tnamePrefix
QUERY;
        $param = array( ":engine"      => "MyISAM", 
                        ":tnamePrefix" => "P%" );
 
        $stmt = execute( $conn, $sql, $param );
 
 
        echo "test case 2----------------------------------------------------\n";
        while( $row = $stmt->fetch(PDO::FETCH_ASSOC ) ) { 
            echo $row[ "engine" ] . " => " . $row[ "table_name" ] . "\n";
        }
 
    } catch ( PDOException $ex ) {
        $ermsg =  $ex->getMessage();
        return null;
    }
    $conn = null;
}
?>



ちゃんとバインド変数を適用して、SQLを発行してくれます。

test case 2----------------------------------------------------
MyISAM => PARTITIONS
MyISAM => PLUGINS
MyISAM => PROCESSLIST







lolipopで、DB接続情報を確認する方法は、前回の記事を参照してください。


また、PDO使用時に文字コードを指定したい場合は、以下の記述でOKです。

    $pdo = new PDO("mysql:host=" . $server . "; dbname=".$database, $user, $pass );




    $pdoParam = array( PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET utf8" );
    $pdo = new PDO("mysql:host=" . $server . "; dbname=".$database, $user, $pass, $pdoParam );


lolipopで、PHP-MySQLを使用してDBに接続する

lolipopでPHP-MySQLを使用した、動作確認用のプログラムを作ってみた。

INFORMATION_SCHEMA.tablesの中身をダンプしてます。

<?php
//---------------------------------------------------
// DBに接続する
//---------------------------------------------------
function getConnection() {
    $server   = "mysqlxxx.phy.lolipop.jp";              // 実際の接続値に置き換える
    $user     = "LAxxxxxxxx";                           // 実際の接続値に置き換える
    $pass     = "xxxxxxxxxx";                           // 実際の接続値に置き換える
    $database = "LAxxxxxx-dbname";                      // 実際の接続値に置き換える
 
    //-------------------
    //DBに接続
    //-------------------
    $conn = mysql_connect( $server, $user, $pass );
    mysql_set_charset( 'utf8', $conn );
 
    //-------------------
    // データベース選択
    //-------------------
    mysql_select_db( $database, $conn );
 
    return $conn;
}
 
//---------------------------------------------------
// SQLを実行する
//---------------------------------------------------
function execute( $conn, $sql ) {
    $result = mysql_query( $sql, $conn );
 
    //データ取得
    mysql_data_seek( $result, 0 );
    return mysql_fetch_array( $result, MYSQL_ASSOC );
}
 
function testMain() {
    //sql実行
    $conn = getConnection() ;
    $sql  = "select * from INFORMATION_SCHEMA.tables";
 
    $rset = execute( $conn, $sql );
    return $rset;
}
?>
 
<!-- 検索結果をダンプする -->
&gt;pre>
<?php var_dump( testMain() ); ?>
</pre%lt;



DBの接続情報(プログラムの6~9行目)は、Lolipopの管理画面から確認できます。
左メニューからデータベースを選択して…


接続したいDBを選択すると、表示されます。


うまく動作すると、以下のような感じで、なんか情報が出てきます。




と、ここまで書いたところで、PHP-MySQLだとプリペアステートメントが使えないことに気付いた…
さすがにプリペアステートメントが無いと実用的なプログラムが書けないので、調べた意味が無かったよ


どうやら、mysqli,PDO,DBIあたりのライブラリを使用しないとダメっぽい。
事前調査が甘いなぁ…


1/31追記:PDO版で接続確認しました↓
lolipopで、PHPとPDOを使用してDBに接続する

絶対暗記したいzen-coding表記 Best20


エディタにZen-Codingのマクロを入れたら、htmlの作成が捗るようになった。
秀丸マクロでZen-Coding


上記のリンク先には、あらゆるZen-Codingの表記法が書かれているけど、一度にマスターするのは大変なので最低限暗記したい表記を厳選して纏めてみた。

pdf版も作ったので、印刷したい人はどうぞ。
CheatSheet > zenCoding-best20.pdf




1:htmlタグ全体

html




<html></html>






2:htmlタグ全体を、xml形式で

html:xml




<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja"></html>





3:htmlタグ全体を、html5形式で

html:5




<!DOCTYPE HTML>
<html lang="ja-JP">
    <head>
        <meta charset="UTF-8" />
        <title></title>
    </head>
    <body></body>
</html>





4:htmlヘッダのcharset定義

meta:utf




<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />





5:htmlヘッダのcss定義

link:css




<link rel="stylesheet" type="text/css" href=".css" />





6:htmlヘッダのscript定義

script




<script type="text/javascript"></script>





7:htmlヘッダのscript定義(src付き)

script:src




<script type="text/javascript" src=""></script>





8:表題

h2




<h2></h2>





9:リンク(aタグの場合はhrefが自動で付与される)

a




<a href=""></a>






10:#で始まるものは、divタグのID指定とみなされる。

#head




<div id="head"></div>






11: .で始まる場合はclass指定

.head




<div class="head"></div>






12: タグ名を#の前に書いた場合は、そのタグで括ってくれる

p#head




<p id="head"></p>






13: 「#」はひとつだけだが、「.」複数指定可能

p#head.large.left




<p id="head" class="large left"></p>






14: タグをスペース区切りで記述するとネストしてくれる

table tr td




<table>
    <tr>
        <td></td>
    </tr>
</table>





15: タグの後に「*」と数字を書くとその回数分繰り返す

ul li*3




<ul>
    <li></li>
    <li></li>
    <li></li>
</ul>





16: &で終わると、htmlエンコーディングしてくれる

ul li&




&lt;ul&gt;
    &lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;





17: 繰り返しさせる固まりは、括弧で指定可能

dl (dt+dd)*2




<dl>
    <dt></dt>
    <dd></dd>
    <dt></dt>
    <dd></dd>
</dl>






18: 括弧で属性値を指定すると、属性値付きになる。

※ただ、aタグの場合は、属性値を書くよりクリップボードに入れておいたほうがbetter
 ”a”の変換後hrefの中にカーソルが移動するので,”a”だけ変換させてCtrl-vした方が速い

a:[href=foo.com]




<a href="foo.com"></a>






19: タグ名の後に”+”をつけると、いつものパターンで子要素を書いてくれる
(他にol,ulとかもいける)

table+




<table>
    <tr>
        <td></td>
    </tr>
</table>






20: ちょっと応用編。formタグを一気に作る。

"form:get ( 
input:text#txtMail + 
input:btn#btnSet
)"




<form action="">
<input type="text" name="" value="" id="txtMail" />
<input type="" name="" value="" id="btnSet" />
</form>






上記内容のPDF版です。 > zenCoding-best20.zip


参考資料:もっと勉強したい人は、以下のページでどうぞ。
秀丸マクロでZen-Coding
zen-coding CheatSheets

[WordPress]今月の投稿数を取得して表示させる


WordPressで、当月の投稿数を取得して画面に表示させてみました。
ちょっとテストしてみたところ、うまくいったのでメモしておきます。


やりたいこと

毎日Blogを欠かさず書く習慣づけを行いたい。
たくさんの記事を提供したい。


考えたこと、やりたいこと

  • 「毎日がんばる」的な精神論だと飽きるので、Blogの投稿をする為の動機付けを作りたい。
  • 計測できるものは改善できる。な、はず。
  • そのきっかけとして、常に前月の投稿数実績と比較できるようにしたい。
  • 取得した実績は、管理ページのトップに常に表示させたい。

いきなり目標に到達するにはハードルが高いので、まずは調査を兼ねて、WordPressの当月投稿数を取得し、投稿数+累積数を表示させてみます。


データの取得

まずは、目的データを取得する方法の確認です。

MySQLのDBを直接チェックしたところ、投稿データはwp1_postsテーブルに入っていっていました。
ですが、WordPressの場合はテーブル名の接頭語がインストール時に指定可能なので、プログラム上で、上記テーブルを直書きすることはできません。

では、どうするかというと、WordPressでは以下の変数で上記のテーブルが取得できます。また、この変数はDBのコネクション管理もしているので、$wpdb->get_results()でSQLが直接発行できます。

$wpdb->posts



仕組みは分かったのでデータを取得したいのですが、データの中身をを直接チェックしたところ、データの取得は以下の関数でとれるようです。

<?php
//------------------------------
// 今月の投稿数を取得する
//------------------------------
function getThisMonthEntryQty( $wpdb ) {
    $sql = <<<QUERY
        SELECT   DATE_FORMAT( POST_DATE, '%Y%m%d') targetdate,
                 COUNT(*)                          count 
        FROM     $wpdb->posts
        WHERE    POST_TYPE   =  'post'
        AND      POST_STATUS =  'publish'
        AND      POST_DATE   >= CONCAT( DATE_FORMAT( NOW(), '%Y%m'), '01' )
        GROUP BY date_format( POST_DATE, '%Y%m%d')
        ORDER BY POST_DATE
QUERY;
 
    return $wpdb->get_results( $sql );
}
?>



表示側のロジック


表示側はこんな感じ。
本当はグラフにしたいけど、今回は実験なので表形式で出力させます。

<h2>今月の投稿数</h2>
<table>
    <tr>
        <th>日付</th>
        <th>投稿数</th>
        <th>累積投稿数</th>
    </tr>
    <?php $totalcount = 0; ?>
    <?php foreach ( getThisMonthEntryQty( $wpdb ) as $d ) { ?>
    <?php $totalcount += $d->count; ?>
        <tr>
            <td><?php echo $d->targetdate; ?></td>
            <td><?php echo $d->count;      ?></td>
            <td><?php echo $totalcount;    ?></td>
        </tr>
    <?php } ?>
</table>





動作確認


とりあえずのテストとして、single.phpに以下のコード(と関数定義)を追加し、画面を表示させてみます。


期待した結果が出力されました。



TODO

この次にやりたいことメモです。
  • この表示を管理ページで閲覧可能にする。
  • 結果を積み上げグラフで表示可能にする。
  • 当月の累積投稿数と、前月を比較できるようにする。

管理ページに表示させるためには、プラグインを作らなければいけないはずなので、その辺の調査が次のステップになりそうです。

はてブのブログパーツのレイアウトをcssで変更する

ブログパーツを追加してみた

はてなブックマークで人気エントリーの一覧を表示させるブログパーツをサイドバーに追加しました。
追加時したコードは以下の通り。

<div style="margin:-10px;padding-bottom:20px;">
    <script language="javascript" type="text/javascript" src="http://b.hatena.ne.jp/js/widget.js" charset="utf-8"></script>
    <script defer language="javascript" type="text/javascript">
    Hatena.BookmarkWidget.url   = "http://nanoappli.com";
    Hatena.BookmarkWidget.title = "人気の記事";  // タイトル
    Hatena.BookmarkWidget.sort  = "count";       // hot:新着エントリー count:人気エントリー
    Hatena.BookmarkWidget.width = 280;           // パーツの横幅
    Hatena.BookmarkWidget.num   = 5;             // 表示するエントリー数
    Hatena.BookmarkWidget.theme = "default";
    Hatena.BookmarkWidget.load();
    </script>
</div>




表示させてみると、色合いが周りと違うので、ものすごい浮いている…


なので、cssを追加して、他の部品と色合いを合わせてみました。



デザインをcssで変更する

ページロード後のhtmlをfirebugをチェックしてみると、タグに”.hatena-bookmark-xxx”のクラスが指定されている模様。
他のサイドバーと色合いを合わせるべく、各部品のcssを試行錯誤で修正してみました。

追加したcssは以下の通り。

 
<style type="text/css">
<!--
/* タイトル一覧の背景を透明にする */
.hatena-bookmark-widget-title, .hatena-bookmark-widget-title a {
  background-color: #F9F9F9        !important;
  border-bottom: 0px               !important;
  background-image: none           !important;
  font-size: 12px    !important;
  font-weight: bold  !important;
  color:#333333      !important;
  border-radius: 0 0;
  -moz-border-radius: 0 0;
  -webkit-border-radius: 0 0;
}
/* 記事一覧の背景を透明にする */
.hatena-bookmark-widget-body ul {
  background-color: transparent !important;
}
/* 記事一覧のタイトル文字の装飾を変更する */
.hatena-bookmark-widget ul li a.hatena-bookmark-entrytitle {
    color: #333333;
    text-decoration: underline;
}
 
/* 記事一覧のタイトル下部にある線を消す */
.hatena-bookmark-widget ul li {
	border-bottom: 0px !important;
}
-->
</style>




CSSを適用して、再表示させると…


いい感じになりました。
本当は、フッタのロゴもdisplay:noneにしたいところだけど、そこまでするのもやりすぎな気がするのでこの辺で留めておきます。