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

エンタープライズIT系エンジニアのぼやっきー

特にまとまりもなく、色々なことをぼやきます。最近はオープンソースの業務系システムに興味あり。

iOSのFacebook SDKで従来のネイティブアプリ認証を行う方法

※この記事はFBSDKCoreKit 4.16, FBSDKLoginKit 4.16で試した結果です。
※こんなことをせずともFacebookアプリで認証が出来る日を願っています。

Facebook SDKでログインする際にiOS 9から標準状態ではSFSafariViewControllerを使うようになったそうです。

従来はFacebookアプリに遷移して認証をしていたので、Facebookアプリを使ったことがあればそれの認証情報でログインが済みました。
しかし、iOS 9からFacebookアプリを開く前にアラートを出すようになって、ユーザビリティが激落ちしたからSafariで開こうぜ、という謎理論によって変更されました。

むしろSafariFacebookログインしたことないと、ログインしなきゃいけなくてクソ面倒なんですが。

そんなことで従来の方式に戻す方法。

FBSDKServerConfiguration.m

- (BOOL)useNativeDialogForDialogName:(NSString *)dialogName
{
    return @YES;
}

そう、FBSDKServerConfiguration.mのファイルを開いて戻り値を@YESに変えるだけ。

新社会人に伝えたい3つのこと

新社会人の皆さんは、研修に行って社会人になった感覚がない方や、あるいは実戦投入されて毎日がとても大変な方もいることでしょう。

社会人の先輩として3つだけ皆さんにお伝えしたいことがあります。

まずは手に職を付けなさい

システムエンジニアであればプログラミングできるようになりなさい、とかサーバの構築、運用ができるようになりなさい、とかです。

営業であれば、トークスキルやどうやったら受注に繋がるのかスキルとして身に付ける、経理であれば会計処理、企業の決算処理の方法などを身につけるということです。

ただ身に付けるのではなく、同業の人が1000人集まってもNo.1になれるぐらいのレベルを目指してください。

もし、あなたが会社の倒産や、何かしらの理由によって会社を去る時に高いスキルを持っていれば仕事に困ることはありません。

また、高いスキルがあればリストラなどの憂き目に遭う可能性をぐっと下げることができます。

改善できる人になりなさい

飲み会やちょっとした雑談で、誰かをけなす、あるいは会社や何かを批判することは別に構いません。

しかし、覚えておいて欲しいのは「批判することは誰にでも出来る」ということです。

そして「悪いところを改善できる」のは誰でも出来ることではありません。何かを改善するためには批判する以上の考える力や行動力が必要で、他の誰よりもそれに対して時間を費やさなければなりません。

批判だけをする小さな人間にならず、是非とも改善できる人になってください。

本当にダメだと思ったら辞めなさい

あなたが心の底から本当に辛いと思った時、命を絶とうと思った時、全力で逃げなさい。

仕事はいくらでもあります。生き方も自由です。

もし、それを避難されても恥ずべきことは一つもありません。

 

[PR] 日本でまともに使えるオープンソースCRMが出ています。
f:id:junmt:20151117120041p:plain
CRM構築はオープンソースのF-RevoCRM -エフレボシーアールエム- 

Webデザイナー志望の学生さん、当社で勉強してみませんか?

こんな人を探しています。

・学生の内に企業で働くことを体験してみたい
・学生の内にWebデザインで実績を残したい
 (自分のWebデザインスキルを実際の企業で試してみたい)

当社は従業員6名ぐらいのIT系のベンチャー企業です。
企業向けのWebアプリケーション開発を中心にやっています。

実はデザイン系が非常に苦手な会社です。
そのためデザイナーさんに頼んでホームページなどリニューアルなどしていますが、全く追いついていない状態です。

現在、製品サイト2個、新製品のデザインが未着手で残っています。
こんな状況なので、思い切ってこれを学生さんのチャレンジの場として提供してみることにしました。

(でも、色々と自信がないのでこっそりと応募です。むしろ誰の目にも止まらない自信はあります。)

あくまでチャレンジの場なので、失敗しても構いません。
自分のデザインが採用されれば、自らの実績としていくらでも使っていただいて構いません。

学生さんのメリット

  • 採用されたWebデザインを実績として使え、就職活動を有利に進めることができる
  • 非常にレベルの高いWebアプリケーションエンジニアと接することができる
  • つい最近まで東証一部上場企業の面接官だった人と面接の練習や相談ができる
  • そのまま当社に就職できる可能性がある

こんな人が向いています

  • 就職前に自分のデザイン力を試してみたい
  • 就職活動を有利に進めたい
  • Webデザインでチャレンジしてみたい

こんな人はダメです

  • Webデザインに興味がない
  • アルバイトでお金が欲しい
  • 暇を潰したい

その他

  • PCは貸し出します。あんまりスペックが良くないので持ち込みでもOKです。
  • 場所は小伝馬町と人形町の間ぐらいです。
  • 交通費は全額支給します。(都心から遠い人は検討させてください。。)
  • ランチ代ぐらいは出せるように調整中です。。
  • アルバイトではないので、その他を支給する予定はありません。

応募方法

j_matsudaあっとc-cube-design.jp までメールをください。

応募期限はとりあえず2/12(金)まで。
それが過ぎても延長しようと思っていますが、状況が変わってしまうかもしれないので一応期限を設けています。

ドメインにdesignって付いていますが、このドメインは実は関係ない・・・

ferretのCRMツール16選を分析、ツッコミ

以下がたまたま目に止まってモヤモヤしたので、ツッコミを入れます。
無知だったのだろうか、それとも作為的なんだろうかわからないが、CRMを比較したことがある身としては見過ごせない気がしています。
ferret-plus.com

※以下は2015/12/18 13時時点の情報を元に書いています。

掲載の順番がよくわからない

eセールスマネージャーの順番がR-CRM、顧客創造Approachよりも下

Sales CloudやDynamicsCRMが上位に来るのは、知名度からしても納得します。
しかし、eセールスマネージャーはCRMとしてもそれなりに高機能であるにも関わらずこれほど下に持ってくる意味がわかりません。

また、文頭にあるリードナーチャリングの面でも十分に使い易い機能があります。*1

なお、カスタマーリングスより上かどうかと言われると、カスタマーリングスの方が「顧客管理」「リードナーチャリング」の視点からすれば上に見えます。

eセールスマネージャーよりもSynergy!が下

「顧客管理」「リードナーチャンリグ」の視点であればSynergy!がeセールスマネージャーよりも上のような気がします。
ただし、CRMという枠でみればeセールスマネージャーの方が圧倒的に高機能なためこういう順番になったのかもしれません。

ここは賛否分かれそうです。

BusinessViewを入れた意味がわからない

BusinessView自体をよく知らないので、私の勘違いかもしれませんが、サイトの情報を見る限りコールセンターに特化したアプリケーションのように見えます。
他の紹介が汎用性の高いCRMであるにも関わらず、業種に特化したCRMを入れたのかわかりません。

また、J2EEフレームワークの採用は利用者に何もメリットをもたらさないので、さらに違和感を覚えます。

だったら、他の会社だってフレームワークを使っているでしょうから、Springの採用、Playframeworkの採用、CakePHPの採用、Larabelの採用、Ruby on Railsの採用...とか言い放題になってしまうでしょう。

Sansan, Skydesk, F-RevoCRM, VtigerCRMが入っていない

CRMGoogle検索するとSansanは出てこないので納得かもしれません。
一時期、SansanってCRMとか自称していたような気がしますが・・・。

どちらにせよ、Skydeskは1ページ目に表示されているので、知らなかったとは思えません。
文頭の「顧客管理」「リードナーチャリング」の意図からしても除外する理由がないと感じます。

また、F-RevoCRMも4ページ目に位置しているため、スポンサーになりえないオープンソースを意図的に除外したと感じます。
仕方ないと言えば、仕方ないが応援しているこちらとしては18選にして一番下にF-RevoCRMとVitgerCRMを入れて欲しかったと思います。


[PR] 日本でまともに使えるオープンソースCRMが出ています。
f:id:junmt:20151117120041p:plain
CRM構築はオープンソースのF-RevoCRM -エフレボシーアールエム-

*1:ただし、オープンソースのMauticやパイプドビッツ社のSpiralなどの製品と比較するとMarketing Automationの領域までは作り込まれていない。

今更ながらにマイナンバーについて考えてみた

f:id:junmt:20151217140133p:plain
最近、マイナンバー関連の報道を見かけなくなり、すっかりと落ち着いてきました。
しかし、問題が起こるのはこれからで別に全ての問題が解消されたわけではありません。

ひとまず、自分の中でも整理がついていなかったので考えてみました。

マイナンバーは必ず流出する

マイナンバーは必ず流出します。

マイナンバーを管理するのはコンピューターだけではありません。
人の介在が絶対不可欠なため、流出のリスクが常につきまとうことになります。

また、マイナンバーを管理しているコンピューター*1も人によって管理されています。
暗号化などをいくらしようが、外部アクセス(外的要因)からのリスクを大幅に軽減するだけで、役所の人やサーバ管理者、管理ソフトウェア開発者などの内的要因は防ぎようがありません。

加えて、極端な話をすれば役所の窓口でマイナンバーを伝えた際に、窓口の人が名前とマイナンバーをセットで丸暗記すれば良いということです。

1件流出でも1億件流出でも、流出に変わりなく、流出したマイナンバーが悪用されれば被害を被る人が必ず現れます。

ほとんどの人が被害に遭うことなく一生を終えるだろうと思っていますが、もう一方では交通事故のようにいつ遭うものかわからないものです。

流出した際にどうすればいいのか?

発覚したら、すぐにJ-LISのコールセンターに連絡をして番号の一時利用停止を行ってください。
2015/12/17時点では各市町村でも番号の変更ができないようなので、今後どうすれば良いかも相談してみると良いかもしれません。

クレジットカードなどと同じく、とにかくすぐに停止するのが良いと思います。

地方公共団体情報システム機構 地方公共団体情報システム機構

※何かしら被害が出ている場合はそれらに関連する会社などにも連絡が必要でしょう。
※2015/12/17時点の話なので、他にも被害拡大防止のために連絡が必要な機関が増えるかもしれません。

流出を覚悟しておくこと

2016年の年末から年末調整の用紙にもマイナンバーの記載が必須になります。
そのため、誰かしらの目に触れることは避けられません。

ひとつ言えるのは、流出しても慌てず番号の一時利用停止を行うこと。
被害が出てしまったものを嘆くよりも、被害が拡大しないように抑え込む行動が必要になります。

また、どこでどのように使われるのかはその時に調べた方が良いと思われます。
今ここで書いてもその時には古い情報になってしまい役に立たないことやミスリードしてしまう可能性があるため、あえて書きません。

書いていて思ったこと

マイナンバー関連の損害に対する保険があったら嬉しいですね。
例えば、月額数百円とか少額で、何かあれば全額補償とかしてくれるとか。

被害に遭う確率はとてつもなく低く、杞憂に終わるかもしれませんが、実際に被害に遭った時に備えたい気持ちもあります。

ただし、国がこの補償をやってはいけないと思います。
役人はホイホイ騙されてしまいそうなので、保険業を専門とする会社がやってほしいです。

なんにせよ、別に悲観的に見ているわけでもなければ楽観的に見ているわけでもなく、厳密な情報管理や抜け漏れ防止のためにマイナンバーはいつかは始まるものだと思っていましたし、それがたまたま今だったと思っています。


[PR] 日本でまともに使えるオープンソースCRMが出ています。
f:id:junmt:20151117120041p:plain
CRM構築はオープンソースのF-RevoCRM -エフレボシーアールエム-

*1:例えば、サーバとか、ネットワーク機器とか良い呼称が思いつかなかったので、コンピューターの一括りにしています。

今更ながらNode.jsでPromiseの使用例

今更ながらこの話題を。使い方を間違えるので、私としては co は非推奨。

Node.js でAPIなどを作成するときに、どうしてもDBアクセス等で callback の利用が多くなります。
特に複雑な業務システム系ならばなおさらです。
また、エラーハンドリングの記述が多くなり、ハンドリング漏れの恐れがあります。

そんな時に「Promise」「then」「catch」を使います。

// こんな感じでPromiseオブジェクトを生成
var promise = new Promise(function(resolve, reject){
  // 非同期処理
  setTimeout(function(){
    try {
      var result = hoge();
      resolve(result);
    } catch(err) {
      reject(err);
    }
  }, 1000);
});

// コールバックに相当する部分
// thenはチェインできるので、上記にそのまま .then で繋げてもOK
promise.then(function(result){
  //引数はresolveの引数がそのまま渡されてくる
  console.log(result);
});

// reject または エラーが throw された場合に呼ばれる部分
promise.catch(function(err){
  console.log(err);
});

まずはこれが基本形です。

次にちょっと応用してみます。

var promise1 = new Promise(....略).then(...略).catch(...略);
var promise2 = Promise.resolve().then(...略);

// 1. 順序を保証して実行
var serial = Promise.resolve().then(function(){
  return promise1;
}).then(function(promise1_result){
  return promise2;
});

// 2. 順序に関わらず実行
var parallel = Promise.all(
  [promise1, promise2]
).then(function(result){
  console.log(result); // [promise1_result, promise2_result]
});

1.の場合はpromise1の次にpromise2がコールされます。
もし、promise1でエラーが発生して、catchが呼ばれても次の「then」の中にあるpromise2が呼ばれます。
そのため、この「then」は try-catch-finally の finally に相当させることができます。

2.の場合はpromise1とpromise2が順序を問わず実行されます。
片方の終了を待たず、時多重分割でお互いに割り込みのタイミングがあれば割り込みながら実行されていきます。

なお、さらりと出してしまいましたが、以下は同等です。

// 何もせずにresolve()がコールされたPromiseオブジェクト
var promise1 = new Promise(function(resolve, reject){
  resolve();
});

// 何もせずにresolve()がコールされたPromiseオブジェクト
var promise2 = Promise.resolve();

// 何もせずにreject()がコールされたPromiseオブジェクト
var promise3 = new Promise(function(resolve, reject){
  reject();
});

// 何もせずにreject()がコールされたPromiseオブジェクト
var promise4 = Promise.reject();

Promiseで最も重要なのは、thenの使い方です。

例えば、以下のような形。

悪い例

Promise.resolve().then(function(){
  Promise.resolve().then(function(){
    throw new Error();
  };
}).catch(function(err){
  console.log(err);
});

良い例

Promise.resolve().then(function(){
  return Promise.resolve().then(function(){
    throw new Error();
  };
}).catch(function(err){
  console.log(err);
});

良い例は then 内で Promise を return しています。
これによって、throw new Error() された際に catch で捕まえることができるようになります。

何が言いたいかというと、以下のような書き方ができるということです。

var conn = null;
var transaction = new Promise(function(resolve, reject){
  // データベースのコネクションを取得する
  ConnectionPool.getConnection(parameters, function callback(err, connection){
    if(err){reject();}
    conn = connection;
    resolve();
  });

}).then(function(){
  // 何かしらQueryを流して、その後の処理を実行とか
  return new Promise(function(resolve, reject){
    conn.query(...省略)
  });

}).then(function(){
  // 問題なくここまでくればcommit。
  if(conn) {
    conn.commit();
  }

}).catch(function(err){
  console.log(err);
  // エラーがcatchされたらrollback。
  if(conn) {
    conn.rollback();
  }

}).then(function(){
  // 最後に必ずコネクションを解放する
  if(conn) {
    ConnectionPool.release(conn);
  }
});

then の中で reject したい

then の中は Error が throw されれば reject 扱いとなります。
しかし、想定されるエラーや強制的に reject をコールしたい場合は以下のようにしたほうが良いと思っています。
個人的に読みやすいですし、then の中も Promise であると考えると納得感があります。

Promise.resolve().then(function(){
  if(err) {
    return Promise.reject(err);
  }
});

使ってみた感想

co を使えばもっとすっきり書けます。
しかし、co はとりあえず括っておいて、yield 付ければいいんでしょ的な考えに落ちやすくダメコードを書いてしまいます。
例えば、DBコネクションを使いまわしてトランザクションを一気にロールバックしたい時に、function 毎に co を呼んでいることが原因で、上手くエラーハンドリングできないことが発生します。というか、恥ずかしながら私がそうなって泣きながら大量のコードを修正しています。。
それであれば、Promise/then/catchで書いた方が、わかりやすくて個人的に好みです。


[PR] 日本でまともに使えるオープンソースCRMが出ています。
f:id:junmt:20151117120041p:plain
CRM構築はオープンソースのF-RevoCRM -エフレボシーアールエム-

MySQL 5.7.10 の導入は見送ります

MySQL 5.7 になってからオプティマイザが賢くなったとか、かなりの期待感を持っていたため、ローカルや本番用のサーバに入れて検証をしてみました。

結論から言えば、MySQL 5.6 からデグレしています。
ちなみに、全く別件の障害対応に追われているため、原因調査はできていません・・・。

環境

  • MySQL 5.7.10
  • MySQL 5.6.27 (5.7固有の問題か切り分けるために使用)

MySQL 5.7.10の問題は MacOS 10.11.1 と CentOS 7 の両方で確認。

問題1 MySQLのサービスが応答を返さなくなる

  • 10テーブル(それぞれ数百万〜数十万件)に対してDelete文を発行
  • 結果は数件削除(正しい結果)
  • その後から他の接続が全くできなくなる【謎】
  • サービスを再起動して、復旧

データを復元して同じクエリを流すと再現します。
また、Delete文だけでなく、Insertや大量にデータがヒットするSelectでも再現。

特徴といえば、それぞれのテーブルがパーティショニングされていることでしょうか・・・。

MySQL 5.6 では再現せず。

問題2 PKを条件に含むexists句の挙動がおかしい

SELECT
  A.*,
  B.ID,
  B.NAME,
  B.HOGE,
  C.ID,
  C.NAME,
  C.HOGE
FROM
  A
  LEFT OUTER JOIN B ON (B.A_ID = A.ID AND B.USER_ID = ?)
  LEFT OUTER JOIN C ON (C.A_ID = A.ID)
WHERE
  (
    EXISTS(
      SELECT
        1
      FROM
        D
      WHERE
        D.A_ID = A.ID AND
        D.USER_ID = ?
    ) OR
    EXISTS(
      SELECT
        1
      FROM
        E
      WHERE
        E.A_ID = A.ID AND
        EXISTS(
          SELECT
            1
          FROM
            F
          WHERE
            F.E_ID = E.ID AND
            F.USER_ID = ?
        )
    )
  ) AND
  A.ID = ?

※実際にシステムが流したクエリに基づくため、違和感を覚えると思いますが、とりあえず事実を伝えたいのでこれで。

参照権限のチェックをクエリで表現してしまったため、ずいぶんと変なクエリですが、これを実行すると対象レコードが存在するにもかかわらず結果が0件になることがあります。
また、最後の「A.ID = ?」でPrimary Keyを条件にしていること問題のようで、「A.NAME = ?」にして完全一致で名前を入れると対象レコードが取得できます。

面白いのは「D.A_ID = A.ID」のようになっているところを「D.A_ID = ?」などにして「A.ID = ?」で指定している値を入れるとレコードが取得できます。

explainを取っていないとわかりませんが、実行順序で何か問題が起こっているものと思われます。
当然、MySQL 5.6 では再現せず。

# そもそもそんな複雑なクエリをMySQLで流すな、ということかもしれませんが。

まとめ

まだ本番運用では怖いです。
やはり網羅的にテストを行ってからバージョンアップしたほうが良さそうです。

# 個人的にはOracleSQLServerが安定しているし、実行速度も速いのでそちらを使いたい・・・高くて予算取れないけど。


[PR] 日本でまともに使えるオープンソースCRMが出ています。
f:id:junmt:20151117120041p:plain
CRM構築はオープンソースのF-RevoCRM -エフレボシーアールエム-