mysqldump → リストアで外部キー制約エラーの回避 

MySQL で、外部キーのあるテーブルがあるスキーマを mysqldump で採取した SQLソースを
そのままリストアに使うと
Foreign key constraint is incorrectly formed
となる場合がある。

そんな場合の解決方法、、

SET FOREIGN_KEY_CHECKS=0;

をSQLの先頭に記述

SET FOREIGN_KEY_CHECKS=1;

で、元に戻す。

JavaScript JSON のパターン・キーの値が全て同じかどうか調べる

Java ではなくて JavaScript の処理です。(あまり書きたくない JavaScript です。様々な理由で書きます)
お題:以下のJSON で、unit001~3 のキーの値が全て同じであるか調査します。

const obj = {
    unit001: '0_1_2',
    unit002: '0_1_2',
    unit003: '0_1_2',
    unbinuty: '0_1_2',
};

最初に、以下のサイトの記事を参考にさせて頂いて書いてみたもの。
  https://www.nxworld.net/tips/js-array-filter-snippets.html
(ありがとうございます。)

let a = new Array();
Object.keys(obj).filter(function(d){
    return d.match(/unit[0-9]+/);
})
.forEach(function(key) {
    a.push(obj[key]);
});
const getUniqueValues = ([...array]) => {
    return array.filter((value, index, self) => self.indexOf(value) === self.lastIndexOf(value));
};

if (getUniqueValues(a).length==0){
   console.log("全て同じ");
}else{
   console.log("全て同じでない");
}

もっと簡潔に、、

let aa = Object.keys(obj).filter(function(d){
    return d.match(/unit[0-9]+/);
}).map(function(key){
    return obj[key];
}).filter((v, index, self)=> self.indexOf(v) === self.lastIndexOf(v));

if (aa.length==0){
   console.log("全て同じ");
}else{
   console.log("全て同じでない");
}

URL パラメータを取得するJavaScript

URL パラメータを取得するJavaScript コードは、結構いろんな書き方がネット検索すると紹介されてるが、
cool と思ったものを見つけました。
stackoverflow.com

URL指定もしくは省略でキー名の値を取得

function getUrlParam(name, url) {
   if (!url) url = window.location.href;
   name = name.replace(/[\[\]]/g, "\\$&");
   var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
       results = regex.exec(url);
   if (!results) return null;
   if (!results[2]) return '';
   return decodeURIComponent(results[2].replace(/\+/g, " "));
}

URL指定もしくは省略でパラメータ全てJSONで取得

function getUrlParamJson(url) {
   if (!url) url = window.location.href;
   var match,
   pl     = /\+/g,
   search = /([^&=]+)=?([^&]*)/g,
   decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); };
   var urlParams = {};
   while (match = search.exec(url.split(/\?/)[1]))
      urlParams[decode(match[1])] = decode(match[2]);
   return urlParams;
}
params = getUrlParamJson();
prettyjson = JSON.stringify(params, null, 4)
console.log(prettyjson )

Field の getType は、Class

よく落ち着いてみれば、Java リフレクションの Field の getType の返却は、Class<?>
だから、以前書いた 入れ子構造のBean の中の Obejct を取得する(2) - Oboe吹きプログラマの黙示録
も、以下のとおり書き直せる。

import java.lang.reflect.Field;
import java.util.function.Function;
/**
 * UniqueFieldfinder
 */
@FunctionalInterface
public interface UniqueFieldfinder<T, R>{
   R find(T u);

   @SuppressWarnings("unchecked")
   static <T, R> Function<T, R> of(Class<R> c){
      return t->(R)search(c, t);
   }

   static <T> Object search(Class<T> c, Object o){
      Field[] fs = o.getClass().getDeclaredFields();
      String cname = c.getName();
      for(Field f:fs){
         String typename = f.getType().getName();
         if (typename.startsWith("[")) continue;
         try{
            f.setAccessible(true);
            if (f.getType().isPrimitive() || typename.startsWith("java.") || typename.startsWith("jdk.")
               || typename.startsWith("javax.")   || typename.startsWith("org.xml.")
               || typename.startsWith("org.w3c.")|| typename.startsWith("org.omg.") ){
               if (cname.equals(f.getType().getName())){
                  return f.get(o);
               }
               continue;
            }
            if (cname.equals(f.getType().getName())){
               return f.get(o);
            }
            Object v = f.get(o);
            if (v==null) continue;
            return search(c, v);
         }catch(IllegalArgumentException e){
         }catch(IllegalAccessException e){
         }
      }
      return null;
   }
}

でも、相変わらず、探索に指定する型が重複して持っている場合はうまく取得できない。
List や、Map、Collection は指定して取得できない。
配列も指定して取得できない。

という制約でこれはあまり使いものにならない。

依存関係のライブラリ(JAR)を含めた実行可能JAR を Gradle で作成する

Gradle の jar タスクは以下のようにする。

jar {
    excluse 'MET-INF/*.SF', 'MET-INF/*.DSA', 'MET-INF/*.RSA', 'MET-INF/*.MF', 
    manifest {
        attributes 'Main-Class': 'org.yips.HellowMain'
        'Class-Path': configurations.runtime.files.collect { "lib/%it.name" }.join(' ')
    }
    from configurations compile.collect { it.isDirectory() ? it : zipTree(it) }
}

Class-Path の書き方を上のようにする。

ついでに、作成した jarファイルを別のディレクトリにコピーするタスクは、以下のとおり。
(InteliJ の場合)

task distribute(type Copy){
   from 'build/libs'
   into 'dist'
   include '*.jar'
}

InteliJ でこの distribute タスクは Gradle タブで other の下に作られる。
f:id:posturan:20200206215737j:plain

JSON のソート(Javascript)

Python 使用時の JSON ソートを書いたので、次は JavaScript

oboe2uran.hatenablog.com

同様のJSONデータとする。

var data = {
  "title": "サンプル",
  "records":
   [
     {"item": "item 2", "point": 74.68, "date":"2020-02-01" , "memo":"う" },
     {"item": "item 1", "point": 4.63 , "date":"2020-02-02" , "memo":"あ" },
     {"item": "item 3", "point": 9.38,  "date":"2020-02-05" , "memo": null },
     {"item": "item 4", "point": 5.78,  "date":"2020-02-14" , "memo":"い" },
     {"item": "item 5", "point": 5.53,  "date":"2020-02-07" , "memo":"え" }
   ]
};

日付の昇順

const sorted_records = data['records'].sort((a, b)=> a.date > b.date ? 1 : -1 );

pointの降順

const sorted_records = data['records'].sort((a, b)=> a.date > b.date ? -1 : 1 );

memo のソート、
null がある場合、やはり、そのままではソートできないので、'' 空文字でソートさせる必要がある。

const sorted_records = data['records'].sort((a, b)=>{
   const c = a.memo==undefined ? "" : a.memo;
   const d = b.memo==undefined ? "" : b.memo;
   return c > d ? 1 : -1
});
data['records'] = sorted_records;

どうしても1行で済ませたいなら、括弧でくくる。

const sorted_records = data['records'].sort((a, b)=>(a.memo==undefined ? "" : a.memo) > (b.memo==undefined ? "" : b.memo) ? 1 : -1);