001/*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016package org.opengion.fukurou.db;
017
018import java.io.UnsupportedEncodingException;
019
020/**
021 * JavaDB(derby) や、hsqldb に対する、Javaの拡張組込み関数です。
022 *
023 * staticメソッドとして、関数を定義します。引数や返り値は、各データベースの
024 * 定義に準拠します。
025 *
026 * <pre>
027 * ① JavaDB の場合
028 * 【概要】
029 *     実行するデータベースから見えるところに、ファイルを配置する必要があります。
030 *     java8 までなら、Javaのエクステンション(JAVA_HOME\)jre\lib\ext などですが、
031 *     java9以降は、CLASSPATH に設定します。
032 *     openGionでは、bin/const.bat で、OG_CLASSPATH 環境変数にパスを通して、
033 *     使用しています。
034 *     標準の Java staticメソッドを FUNCTION 定義することも出来ます。
035 * 【設定】
036 *     JavaDBに FUNCTION を定義します。(サンプル)
037 *      DROP FUNCTION TO_CHAR;
038 *
039 *      CREATE FUNCTION TO_CHAR ( VAL DOUBLE )
040 *      RETURNS VARCHAR(20)
041 *      DETERMINISTIC           -- 引数が同じなら常に同じ値を返すことを示す.(省略時はnot deterministic)
042 *      PARAMETER STYLE JAVA    -- 戻り値のタイプ
043 *      NO SQL LANGUAGE JAVA    -- 関数の中でSQLは実行しないことを示す
044 *      EXTERNAL NAME 'org.opengion.fukurou.db.Functions.toChar' ;
045 *
046 * ② HSQLDB の場合
047 * 【概要】
048 *
049 * </pre>
050 *
051 * @og.rev 6.8.5.1 (2018/01/15) org.opengion.javadb → org.opengion.fukurou.db にパッケージ変更
052 * @og.group 拡張組込み関数
053 *
054 * @version  1.1.0
055 * @author       Kazuhiko Hasegawa
056 * @since    JDK8.0,
057 */
058public class Functions {
059    private static final String ENCODE = "UTF-8";
060
061        /**
062         * 数値を文字列に変換します。
063         *
064         * この関数は、引数の double が、小数点を含まない場合は、
065         * 小数点以下を出しません。
066         * JavaDBの場合、数字と文字列の連結が出来ないため、文字列変換関数を用意します。
067         *
068         *      DROP FUNCTION TO_CHAR;
069         *
070         *      CREATE FUNCTION TO_CHAR ( VAL DOUBLE )
071         *      RETURNS VARCHAR(20)
072         *      DETERMINISTIC           -- 引数が同じなら常に同じ値を返すことを示す.(省略時はnot deterministic)
073         *      PARAMETER STYLE JAVA    -- 戻り値のタイプ
074         *      NO SQL LANGUAGE JAVA    -- 関数の中でSQLは実行しないことを示す
075         *      EXTERNAL NAME 'org.opengion.fukurou.db.Functions.toChar' ;
076         *
077         * @og.rev 6.7.3.0 (2017/01/27) 新規作成
078         * @og.rev 6.8.5.1 (2018/01/15) org.opengion.javadb → org.opengion.fukurou.db にパッケージ変更
079         *
080         * @param       val     文字列に変換すべき数値
081         * @return      変換した文字列
082         */
083        public static String toChar( final double val ) {
084                final int intVal = (int)val;
085                return ((double)intVal) == val ? String.valueOf( intVal ) : String.valueOf( val );
086        }
087
088        /**
089         * 特殊な文字列の連結を行います。
090         *
091         * これは、第1引数の数字と、第2、第3、第4の文字列をスペースで連結した文字列を返します。
092         * 引数の個数が、可変に出来ないため、完全に決め打ちです。
093         *
094         *      DROP FUNCTION JOIN2;
095         *
096         *      CREATE FUNCTION JOIN2 ( INTEGER , VARCHAR(2000) , VARCHAR(2000) , VARCHAR(2000) )
097         *      RETURNS VARCHAR(4000)
098         *      DETERMINISTIC                   -- 引数が同じなら常に同じ値を返すことを示す.(省略時はnot deterministic)
099         *      PARAMETER STYLE JAVA    -- 戻り値のタイプ
100         *      NO SQL LANGUAGE JAVA    -- 関数の中でSQLは実行しないことを示す
101         *      EXTERNAL NAME 'org.opengion.fukurou.db.Functions.join2' ;
102         *
103         * @og.rev 6.7.3.0 (2017/01/27) 新規作成
104         * @og.rev 6.8.5.1 (2018/01/15) org.opengion.javadb → org.opengion.fukurou.db にパッケージ変更
105         *
106         * @param       no              第1引数の数字
107         * @param       arg2     第2引数
108         * @param       arg3    第3引数
109         * @param       arg4    第4引数
110         * @return      連結したした文字列
111         */
112        public static String join2( final int no , final String arg2 , final String arg3 , final String arg4 ) {
113                return new StringBuilder()
114                                .append( no ).append( ' ' )
115                                .append( arg2 == null ? "" : arg2 ).append( ' ' )
116                                .append( arg3 == null ? "" : arg3 ).append( ' ' )
117                                .append( arg4 == null ? "" : arg4 ).append( ' ' )
118                                .toString() ;
119        }
120
121        /**
122         * 対象の文字列の部分文字列を置換します。
123         *
124         *      DROP FUNCTION REPLACE;
125         *
126         *      CREATE FUNCTION REPLACE ( VARCHAR(2000) , VARCHAR(2000) , VARCHAR(2000) )
127         *      RETURNS VARCHAR(4000)
128         *      DETERMINISTIC                   -- 引数が同じなら常に同じ値を返すことを示す.(省略時はnot deterministic)
129         *      PARAMETER STYLE JAVA    -- 戻り値のタイプ
130         *      NO SQL LANGUAGE JAVA    -- 関数の中でSQLは実行しないことを示す
131         *      EXTERNAL NAME 'org.opengion.fukurou.db.Functions.replace' ;
132         *
133         * @og.rev 6.7.3.0 (2017/01/27) 新規作成
134         * @og.rev 6.8.5.1 (2018/01/15) org.opengion.javadb → org.opengion.fukurou.db にパッケージ変更
135         *
136         * @param       source 対象の文字列
137         * @param       target 置換したい文字列
138         * @param       replacement 置換する文字列
139         * @return      置換した文字列。
140         */
141        public static String replace( final String source , final String target , final String replacement ) {
142                if( source != null && target != null || !target.isEmpty() && replacement != null && !replacement.isEmpty() ) {
143                        return source.replace( target,replacement );
144                }
145                else {
146                        return source;
147                }
148        }
149
150//      /**
151//       * この文字列内にあるすべてのoldCharをnewCharに置換した結果生成される文字列を返します。
152//       *
153//       * String#replace( char , char )を、繰り返します。
154//       *
155//       * @og.rev 6.7.9.0 (2017/04/28) 新規作成
156//       *
157//       * @param       source 対象の文字列
158//       * @param       target 以前の文字の集合
159//       * @param       replacement 置換する文字の集合
160//       * @return      置換した文字列。
161//       */
162//      public static String translate( final String source , final String target , final String replacement ) {
163//              String rtn = source ;
164//
165//              if( source != null && target != null && replacement != null && target.length() == replacement.length() ) {
166//                      for( int i=0; i<target.length(); i++ ) {
167//                              rtn = rtn.replace( target.charAt(i) , replacement.charAt(i) );
168//                      }
169//              }
170//
171//              return rtn;
172//      }
173
174        /**
175         * substr関数のバイト数版
176         * 過去に、hsqldb 用に作成したJava関数です。
177         *
178         * @og.rev 6.8.5.1 (2018/01/15) org.opengion.hsqldb → org.opengion.fukurou.db にパッケージ変更
179         *
180         * @param       value            変換する文字列
181         * @param       start            変換開始アドレス
182         * @param       length           変換バイト数
183         * @return      変換後文字列
184         * @throws      UnsupportedEncodingException    文字のエンコーディングがサポートされていません。
185         */
186        public static String substrb( final String value, final int start, final int length ) throws UnsupportedEncodingException {
187                String rtn = null;
188                final byte[] byteValue = makeByte( value );
189                if( byteValue != null ) {
190                        rtn = new String( byteValue,start-1,length,ENCODE );
191                }
192                return rtn;
193        }
194
195        /**
196         * length関数のバイト数版
197         * 過去に、hsqldb 用に作成したJava関数です。
198         *
199         * @og.rev 6.8.5.1 (2018/01/15) org.opengion.hsqldb → org.opengion.fukurou.db にパッケージ変更
200         *
201         * @param       value           バイト数をカウントする文字列
202         * @return      バイト数
203         * @throws      UnsupportedEncodingException    文字のエンコーディングがサポートされていません。
204         */
205        public static int lengthb( final String value ) throws UnsupportedEncodingException {
206                return makeByte( value ).length;
207        }
208
209        /**
210         * 指定の文字列をバイトコードに変換します。
211         * 引数の文字列が null の場合は、return は、byte[0] を返します。
212         *
213         * @og.rev 6.8.5.1 (2018/01/15) org.opengion.hsqldb → org.opengion.fukurou.db にパッケージ変更
214         *
215         * @param       value    変換するストリング値
216         * @param       encode   変換する文字エンコード
217         * @return      変換後文字列
218         */
219        private static byte[] makeByte( final String value ) throws UnsupportedEncodingException {
220                byte[] rtnByte = new byte[0];
221                if( value != null ) {
222                        rtnByte = value.getBytes( ENCODE );
223                }
224                return rtnByte;
225        }
226}