u-ryo's blog

various information for coding...

Using Where and Join in Mysqldump

| Comments

基本的にはmysqldumpでwhereにjoinを使うにある通り、

1
mysqldump -uusername -p DatabaseName tableA --single-transaction --were 'id IN (SELECT a.id FROM tableA a JOIN tableB b ON a.b_id=b.id WHERE b.name LIKE "%someone%")'

というわけですが、肝は、

  • --where中でJOINを使うためにsubqueryにする
  • --single-transactionを付けることでmysqldump: Couldn't execute 'SELECT... Table 'a' was not locked with LOCK TABLES (1100)と言われるのを防ぐ

Suddenly Failed to Parse DateTime on JHipster Angular

| Comments

ある時、JHipsterのAngularのUser Managementを久し振りに見てみると、user名など表示されるのが物凄く遅いことがありました。ポツ、また数秒してポツ、という具合に一つ一つの行が表示されていきます。あれぇ? こんなもんだったかなぁ? あまり気にしなかったのですが、流石に新規Userを作成しようとして失敗する段になって、これは何とかしなければと思い始めました。browserでF12を押してみると、どうやらDate Pipeでのparseに失敗している様子。どうして? 前は出来てたのに。serverから来ているJSONをよく見ると、DBからのDateTime部分のObjectがepochSecondとかnano何とかになっていました。検索すると、 Efficient way to have Jackson serialize Java 8 Instant as epoch milliseconds?を見付けて、中身読んでないですが「jackson-datatype-jsr310」を見掛けてあぁー!っと。

jhipsterで新規application作ってそのbuild.gradle見てみると、確かにありましたcompile 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'。 これを、なくてもいいじゃん、と大分前に取っちゃってたんですね。確かにWebアプリ本体には影響なかったので気付きませんでした。あーあ。こういう影響が出てくるですか。なるほど。

Setting Password for Unreachable Mail User on JHipster

| Comments

JHipsterでuserを作る時にmail addressは必須で、 基本的にはnew user作るとJHipsterは裏でmailを投げています。 投げて失敗してもnew userは作れるんですが、passwordを設定できません。 どうしたらいいんだろう? と思ってlog見ていたら、 http(s)://ホスト名/#/reset/finish?key=XXXXXXXXXXXXXXXにaccessすれば通常の手続きに乗れるんですね。 このkeyはどこで規定されるのかと思ったら、JHI_USER.RESET_KEYの値です。 ここだけではダメで、JHI_USER.RESET_DATEnow()等で日付時刻をsetしないと、そしてその時刻から24時間以内にaccessしないと、ならないです。 あるuserのpassword強制resetにも使える、と思います。

ただこれをやると、UserService#completePasswordResetの中のcacheManager.getCacheでヌルポが出るようでどうしようもなかったです。なので、UserService.java中のcacheManager.getCache(...)を(当該method以外でも)全てtry...catchで囲いました。だって無害でしょう?

追記: JHipsterでのlogin dialogには「パスワードを忘れましたか」というlinkがあって、 それを踏むとhttp://127.0.0.1:8080/#/reset/requestというpageに遷移し、 mail addressを入れると、上記初期登録時同様にActivateを要求するmailが飛びます。 初めてやってみました。へぇよく出来てますね。 そのmailに書いてあるURLも初期登録時同様http://127.0.0.1:8080/#/reset/finish?key=XXXXXXXXXXです。

Adding a New Column on JHipster

| Comments

JHipsterでdatabaseのtableに新しいcolumnを足したいと思いました。 Liquibaseで管理されているので、直接DBを変えちゃうと立ち上がらなくなっちゃいます。 結構面倒臭いんですよねLiquibase。

基本的にはUsing JHipster in developmentのDatabase updatesに書いてある通り、です。 3通り紹介されていますが、最初に書かれているentity sub-generatorを使った方が、testやi18n、angular側の面倒も見てくれるので楽です。 但し、generateされるjava/json/ts filesについては、面倒でも一つ一つdiffを見て上書きするか考えた方がいいです。場合によっては上書きしない方がいいcaseもありました(repository class、即ちDBを直接叩くclassとかresource class、即ちRest Controllerとか、i18nのglobal.jsonとか、独自に書いたところがあるものは特に)。

新規にtableごと加える時はこれでいいのかもしれません(以前やってうまく行った薄い記憶がありますがよく覚えてません)。 けれども、既存tableにcolumnを足す、となると、 年月日_changelog.xmlを作ってくれないので、 いくらgradleかけてもDBのtableを変更してくれないんです。 更に、checksumが合わないといって起動しなくなります。 困ります。

なので、2番目の策を合わせてchangelog.xmlを作ってもらいます。 そのためには上記ページに書いてあるように、一旦buildしてからgradle liquibaseDiffChangelog -PrunList=diffLogすると、 class fileのdiffを取ってsrc/main/resources/config/liquibase/changelog/以下にchangelogを作ってくれます。 それをsrc/main/resources/config/liquibase/master.xmlに手で書き入れてからbuildすると、changelogが働いてalter tableしてくれます。 但しその際、元のtableのxml(年月日_added_entity_テーブル名.xml)をもとに戻しておかないと、「checksumが合わない」と言われるでしょう。

...というように、1番目と2番目の合わせ技的なところが最良のように思います。

どうしてもうまく行かない時、最後は以下の手で何とかなります。なりました。

  • DBは自分でalter table
  • checksumはDATABASECHANGELOG.MD5CHECKSUMにあるので自分でupdate table set ...

Number to String on Angular/TypeScript

| Comments

Angularを書いていて、 Type 'string' is not assignable to type 'number'.と言われて驚いたので調べました。 えー、そのくらいよしなに変換してくれるんじゃないのー?! 結構型に厳しいんですね。 Typescript, toFixed. Type 'string' is not assignable to type 'number'(12.32).toFixed(2)とあるので試すとその通りでした。 この2ってなんだろう? と思ったら、「小数点以下第2位までの表示(第3位で四捨五入、無ければ0埋め)」ってことなんですね。