001/*******************************************************************************
002The MIT License (MIT)
003
004Copyright (c) 2024 KILLCODING.COM
005
006Permission is hereby granted, free of charge, to any person obtaining a copy
007of this software and associated documentation files (the "Software"), to deal
008in the Software without restriction, including without limitation the rights
009to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010copies of the Software, and to permit persons to whom the Software is
011furnished to do so, subject to the following conditions:
012
013The above copyright notice and this permission notice shall be included in
014all copies or substantial portions of the Software.
015
016THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
022THE SOFTWARE.
023*****************************************************************************/
024package com.killcoding.jsplus;
025
026import com.killcoding.tool.ConfigProperties;
027import com.killcoding.log.Logger;
028import com.killcoding.log.LoggerFactory;
029import com.killcoding.datasource.DriverDataSource;
030import java.util.Arrays;
031import java.util.List;
032import com.killcoding.tool.CommonTools;
033import java.text.SimpleDateFormat;
034import com.killcoding.datasource.CacheDriverExecutor;
035import com.killcoding.cache.CacheArray;
036import java.io.File;
037import com.killcoding.tool.FileTools;
038import java.util.Map;
039import java.util.ArrayList;
040import java.nio.file.Path;
041import java.nio.file.Paths;
042import java.nio.file.Files;
043import java.sql.Connection;
044import java.util.regex.Pattern;
045import java.util.regex.Matcher;
046import java.lang.reflect.Method;
047import java.util.Iterator;
048import java.util.HashMap;
049import java.util.concurrent.ExecutorService;
050import java.util.concurrent.Executors;
051import com.killcoding.tool.ResultMap;
052import com.killcoding.cache.StoredCache;
053import java.util.stream.Stream;
054import java.io.InputStream;
055import java.io.FileInputStream;
056import java.util.Scanner;
057import java.util.Set;
058import java.nio.charset.StandardCharsets;
059import com.killcoding.tool.EscapeTools;
060import com.killcoding.tool.CodeEscapeLevel;
061import com.killcoding.cache.AbsCacheApi;
062import java.lang.reflect.Constructor;
063import java.lang.reflect.InvocationTargetException;
064import com.killcoding.cache.CacheArrayFilter;
065import java.io.IOException;
066import java.sql.SQLException;
067import java.net.URLClassLoader;
068import java.sql.Clob;
069import java.io.Reader;
070import java.sql.Blob;
071import com.killcoding.cache.DataObject;
072import com.killcoding.tool.CipherTools;
073import com.killcoding.tool.Base64Tools;
074import java.nio.file.LinkOption;
075import com.killcoding.file.DiskFile;
076import java.sql.Timestamp;
077import com.killcoding.file.BaseFile;
078import java.nio.file.FileAlreadyExistsException;
079import com.killcoding.jsplus.JsPlusContext;
080import java.util.Properties;
081import java.util.concurrent.ConcurrentHashMap;
082import com.killcoding.jsplus.NashornContext;
083import com.killcoding.datasource.Clock;
084import java.util.Date;
085import java.util.concurrent.TimeUnit;
086import java.util.concurrent.ScheduledExecutorService;
087
088public class ScriptConsole implements ConsoleImpl {
089
090        protected Logger log = null;
091        
092    protected static final Map<Integer,ScriptConsole> CONNECT_CONSOLES = new ConcurrentHashMap<Integer,ScriptConsole>();
093        
094        private static DriverDataSource datasource = null;
095
096        protected ConfigProperties datasourceVariables = new ConfigProperties();
097        protected ConfigProperties consoleVariables = new ConfigProperties();
098        
099        protected static ConfigProperties appenvCp = null;
100                
101        protected boolean taskExecuted = false;
102        protected boolean firstOpen = true;
103        private boolean useScriptEnv = false;
104        private boolean useJdbcEnv = false;
105        private boolean useCmdEnv = false;
106        private boolean useGhostEnv = false;
107        private String engineName = null;
108
109        private long preExecuteTime = 0L;
110        private CacheDriverExecutor cacheDriverExecutor = null;
111        private String lastSelectCommand = null;
112        private String intoValue = null;
113        private boolean exportedCompleted = false;
114
115    protected GhostConsole ghostConsole = null;
116    protected CmdConsole cmdConsole = null;
117    protected JsPlusContext jsPlusContext = null;
118    protected String displayEngineName = "script";
119    
120        private static final List<Runnable> exitRuns = new ArrayList<Runnable>();
121        private static final long startedTimeMs = System.currentTimeMillis();
122        private static Path tmpPath = null;
123        private static ExecutorService exitExecute = null;
124        private ScheduledExecutorService scheduleExecutor = null;
125        private final Map<String,Map<String,Object>> scheduleMap = new HashMap<String,Map<String,Object>>();
126        
127        public final static String JS_PLUS_PATH_KEY = "JS_PLUS_PATH";
128        
129        protected CacheArray globalCacheArray = null;
130        protected Runnable callback = null;
131        protected Runnable callbackBatch = null;
132        protected boolean callbackSync = true;
133        
134        public ScriptConsole() {
135                super();
136                initEnv();
137                log = LoggerFactory.getLogger(this.getClass());
138                loadAppenv();
139                reset();
140        }
141        
142        public static String getJsPlusPath(){
143            return System.getProperty(JS_PLUS_PATH_KEY);
144        }
145        
146        private synchronized void initEnv(){
147            String jsPlusPath = getJsPlusPath();
148            if(CommonTools.isBlank(jsPlusPath)){
149                jsPlusPath = System.getenv(JS_PLUS_PATH_KEY) == null ? System.getProperty(JS_PLUS_PATH_KEY) : System.getenv(JS_PLUS_PATH_KEY);
150                
151                if(CommonTools.isBlank(jsPlusPath)) jsPlusPath = CommonTools.getJarPath(ScriptConsole.class);
152                
153                System.setProperty(JS_PLUS_PATH_KEY, jsPlusPath);
154                File logConfFile = new File(String.format("%s/config/Logger.properties",jsPlusPath));
155                if(logConfFile.exists()){
156                    System.setProperty(LoggerFactory.APP_LOGGER_KEY,logConfFile.getAbsolutePath());
157                }
158                System.out.println("SET JS_PLUS_PATH=" + System.getProperty(JS_PLUS_PATH_KEY));
159            }
160                ScriptConsole.initPool();
161        }
162        
163        public void appenvReloaded(ConfigProperties apenvCp){
164            
165        }
166        
167        public void loadAppenv(){
168            try{
169                if(appenvCp == null){
170                    String jsPlusPath = getJsPlusPath();
171                    File _appenvPropFile = new File(String.format("%s/config/Appenv.properties",jsPlusPath));
172                    if(_appenvPropFile != null && !_appenvPropFile.exists()){
173                        _appenvPropFile = new File(String.format("%s/config/appenv.properties",jsPlusPath));
174                    }
175                    if(_appenvPropFile != null && _appenvPropFile.exists()){
176                        final File appenvPropFile = _appenvPropFile;
177                    appenvCp = new ConfigProperties();
178                    Runnable updateRun = new Runnable(){
179                        @Override
180                        public void run(){
181                            Logger.systemDebug(ScriptConsole.class, "Appenv '{}' Reloading...", appenvPropFile);
182                                                List<String> propKeys = new ArrayList(appenvCp.keySet());
183                                                for (String pk : propKeys) {
184                                                        String v = appenvCp.getString(pk, "");
185                                                        if(log.isDebugEnabled()){
186                                                            System.out.println(String.format("Appenv -> %s=%s",pk,v));
187                                                        }
188                                                        System.setProperty(pk, v);
189                                                }
190                            Logger.systemMark(ScriptConsole.class, "Appenv '{}' Reloaded", appenvPropFile);
191                            appenvReloaded(appenvCp);
192                        }
193                    };
194                    appenvCp.load(appenvPropFile,updateRun);
195                    updateRun.run();
196                    }
197                }
198            }catch(Exception e){
199                log.error(e.getMessage(),e);
200            }
201        }
202        
203        public static ConfigProperties getAppenv(){
204            return appenvCp;
205        }
206        
207        private static boolean detectSystemExit() throws IOException {
208        String exitTmpPathStr = String.format("%s/exit.tmp", tmpPath.toString());
209                Path exitTmpPath = Paths.get(exitTmpPathStr);
210                DiskFile exitTmpDf = new DiskFile(exitTmpPathStr);
211                if(exitTmpDf.exists()) {
212                    long exitMs = exitTmpDf.getModifyTime().getTime();
213                    if(exitMs > startedTimeMs){
214                                int size = exitRuns.size();
215                                for (int i = 0; i < size; i++) {
216                                        Runnable exitRun = exitRuns.get(i);
217                                        if (exitRun != null) {
218                                                exitRun.run();
219                                        }
220                                }
221                                return true;
222                    }
223                }
224                return false;
225        }
226        
227        public synchronized static void initPool(){
228                if (exitExecute == null) {
229                String jsPlusPath = getJsPlusPath();
230                String tmpPathStr = String.format("%s/.tmp/",jsPlusPath);
231                tmpPath = Paths.get(tmpPathStr);
232                try{
233                        if (!Files.exists(tmpPath)) {
234                                Files.createDirectory(tmpPath);
235                                Files.setAttribute(tmpPath, "dos:hidden", true);
236                        }       
237                }catch(Exception e){
238                    LoggerFactory.getLogger(ScriptConsole.class).error(e.getMessage(),e);
239                }
240                        exitExecute = Executors.newFixedThreadPool(1);
241                        exitExecute.execute(new Runnable() {
242                                @Override
243                                public void run() {
244                                        while (!Thread.currentThread().isInterrupted()) {
245                                            try{
246                                                Thread.sleep(1000L);
247                                                Thread.currentThread().setName(String.format("DetectSystemExit-PID-%s",ProcessHandle.current().pid()));
248                            
249                            if(detectSystemExit()) break;
250                            
251                                            }catch(Exception e){
252                                                LoggerFactory.getLogger(ScriptConsole.class).error(e.getMessage(),e);
253                                            }
254                                        }
255                                        LoggerFactory.getLogger(ScriptConsole.class).mark("System exit - PID {}.",ProcessHandle.current().pid());
256                                        Logger.systemMark(ScriptConsole.class, "System exit - PID {}.",ProcessHandle.current().pid());
257                                System.exit(0);
258                                }
259                        });
260                }           
261        }
262        
263        public static void setStaticDataSource(DriverDataSource datasource){
264            ScriptConsole.datasource = datasource;
265        }
266        
267        public void setDataSource(DriverDataSource datasource){
268            setStaticDataSource(datasource);
269        }       
270
271        public synchronized DriverDataSource getDataSource() throws IOException {
272            
273            if(datasource == null){
274            File datasourceConfigFile = new File(ScriptConsole.getJsPlusPath() + "/config/DataSource.properties");
275                if(!datasourceConfigFile.exists()){
276                    datasourceConfigFile = new File(ScriptConsole.getJsPlusPath() + "/config/Datasource.properties");
277                }           
278                if(datasourceConfigFile.exists()){
279                    ScriptConsole.datasource = new DriverDataSource(datasourceConfigFile);
280                }else{
281                    ScriptConsole.datasource = new DriverDataSource();
282                    ScriptConsole.datasource.setConfig(datasourceVariables);
283                }
284            }
285            
286                return datasource;
287        }
288
289        public String getIntoValue() {
290                return intoValue;
291        }
292
293        public String getLastSelectCommand() {
294                return lastSelectCommand;
295        }
296
297        public CacheDriverExecutor getCacheDriverExecutor() {
298                return cacheDriverExecutor;
299        }
300
301        public CacheDriverExecutor getCacheDriverExecutor(boolean refreshConnection) {
302                if (refreshConnection) {
303                        open(true);
304                }
305                return getCacheDriverExecutor();
306        }
307
308        public ConfigProperties getConsoleVariables() {
309                return consoleVariables;
310        }
311        
312        public void setConsoleVariables(ConfigProperties consoleVariables) {
313                this.consoleVariables = consoleVariables;
314        }       
315
316        public void setLastSelectCommand(String lastSelectCommand) {
317                this.lastSelectCommand = lastSelectCommand;
318        }
319        
320        public void clearLastSelectCommand() {
321                lastSelectCommand = null;
322        }
323
324        public void into(String name) {
325                consoleVariables.putAndReturnSlef(name, intoValue);
326        }
327
328        public void sleep(String sleepTime) throws Exception {
329                Long ms = ConfigProperties.parseTimeToMs(sleepTime, 0L);
330                Thread.sleep(ms);
331        }
332
333        public String hostname() throws Exception {
334                return CommonTools.getHostname();
335        }
336
337        public void startTask(String taskTimer, String taskFile) {
338                if (taskTimer == null) {
339                        preExecuteTime = 0L;
340                        consoleVariables.putAndReturnSlef("TaskTimer", DEFAULT_TaskTimer);
341                        consoleVariables.putAndReturnSlef("Task", taskFile);
342                } else {
343                        preExecuteTime = 0L;
344                        consoleVariables.putAndReturnSlef("TaskTimer", taskTimer);
345                        consoleVariables.putAndReturnSlef("Task", taskFile);
346                }
347        }
348
349        public void stopTask() {
350                preExecuteTime = 0L;
351                consoleVariables.putAndReturnSlef("TaskTimer", DEFAULT_TaskTimer + "ms");
352                consoleVariables.putAndReturnSlef("Task", null);
353        }
354        
355        public void callback(Runnable callback,boolean callbackSync) throws Exception {
356            if(this.callback == null){
357                this.callback = callback;
358                this.callbackSync = callbackSync;
359            }else{
360                throw new Exception("The GlobalCacheArray callback already exists.");
361            }
362        }       
363        
364        public void callback(Runnable callback) throws Exception {
365            callback(callback,true);
366        }
367        
368        public void callbackBatch(Runnable callbackBatch,boolean callbackSync) throws Exception {
369            if(this.callbackBatch == null){
370                this.callbackBatch = callbackBatch;
371                this.callbackSync = callbackSync;
372            }else{
373                throw new Exception("The GlobalCacheArray callbackBatch already exists.");
374            }
375        }       
376        
377        public void callbackBatch(Runnable callbackBatch) throws Exception {
378            callbackBatch(callbackBatch,true);
379        }       
380        
381        public CacheArray getGlobalCacheArray(long filterTimer,int filterLoopTimer){
382            initGlobalCacheArray(filterTimer,filterLoopTimer);
383            return globalCacheArray;
384        }
385        
386        public CacheArray getGlobalCacheArray(){
387            initGlobalCacheArray(10L,100L);
388            return globalCacheArray;
389        }       
390
391        protected CacheArrayFilter createCacheArrayFilter(long filterTimer,long filterLoopTimer){
392            return new CacheArrayFilter(filterTimer,filterLoopTimer){
393                @Override
394                public void execute(Integer index, Object o) {
395                if(callback != null) {
396                    if(callbackSync){
397                        callback.run();
398                    }else{
399                        Executors.newSingleThreadExecutor().execute(callback);
400                    }
401                }
402                }
403
404                @Override
405                public void executeBatch(Integer batchIndex,List batch) {
406                if(callbackBatch != null) {
407                    if(callbackSync){
408                        callbackBatch.run();
409                    }else{
410                        Executors.newSingleThreadExecutor().execute(callbackBatch);
411                    }
412                }
413                }
414                
415                @Override
416                public void terminated() {
417                log.info("The GlobalCacheArray Terminated.");
418                }
419            };
420        }
421        
422        public void initGlobalCacheArray(long filterTimer,long filterLoopTimer){
423            if(globalCacheArray == null){
424            globalCacheArray = new CacheArray(false);
425            globalCacheArray.filter(createCacheArrayFilter(filterTimer,filterLoopTimer));
426            }
427        }
428        
429        public void initScriptEngineManager() throws Exception {
430            initScriptEngineManager(true);
431        }
432
433        public void initScriptEngineManager(boolean allowAllAccess) throws Exception {
434            String engineName = consoleVariables.getString("ScriptEngine", DEFAULT_ScriptEngine);
435            this.engineName = engineName;
436            System.out.println(String.format("***Current engine is '%s'.***",engineName));
437            boolean isGraalJs = JsPlusContext.isGraalJs(engineName);
438            boolean isNashornJs = JsPlusContext.isNashornJs(engineName);
439            if(isGraalJs){
440                jsPlusContext = new GraalVmContext(engineName);
441            }else if(isNashornJs){
442                jsPlusContext = new NashornContext(engineName);
443            }else{
444            jsPlusContext = new JsContext(engineName);
445            }
446            jsPlusContext.setAllowAllAccess(allowAllAccess);
447            jsPlusContext.initScriptEngineManager();
448            String aesKey = consoleVariables.getString("Script_Cipher_AesKey", DEFAULT_Script_Cipher_AesKey); 
449            jsPlusContext.setScriptCipherAesKey(aesKey);
450            jsPlusContext.put("Console",this);
451            displayEngineName = jsPlusContext.getEngineName();
452            set("Name",displayEngineName);
453        }
454        
455        public JsPlusContext getContext(){
456            return jsPlusContext;
457        }
458
459        public Object eval(String scriptPath) throws Exception {
460                return eval(new File(scriptPath));
461        }
462        
463        public Object eval(File scriptPath) throws Exception {
464                return jsPlusContext.eval(scriptPath);
465        }
466        
467        public void eval(Runnable execRun) throws Exception {
468                ExecutorService exec = Executors.newFixedThreadPool(1);
469                exec.execute(execRun);
470        }               
471
472        public void closeContext() throws Exception {
473                jsPlusContext.close();
474        }
475        
476        public ScriptConsole newBuilder(String _engineName,boolean allowAllAccess) throws Exception {
477            ScriptConsole console = new ScriptConsole();
478            console.useScriptEnv = this.useScriptEnv;
479            console.useCmdEnv = this.useCmdEnv;
480            console.useJdbcEnv = this.useJdbcEnv;
481            console.consoleVariables = (ConfigProperties)this.consoleVariables.clone();
482            console.stopTask();
483            console.datasourceVariables = (ConfigProperties)this.datasourceVariables.clone();
484            console.set("ScriptEngine",_engineName);
485            console.initScriptEngineManager(allowAllAccess);
486            System.out.println("***New ScriptConsole: " + console.hashCode() + "***");
487            CONNECT_CONSOLES.put(console.hashCode(),console);
488            return console;
489        }       
490        
491        public ScriptConsole newBuilder(String _engineName) throws Exception {
492            return newBuilder(_engineName,true);
493        }       
494        
495        public ScriptConsole newBuilder(boolean allowAllAccess) throws Exception {
496            return newBuilder(this.engineName,allowAllAccess);
497        }
498        
499        public ScriptConsole newBuilder() throws Exception {
500            return newBuilder(this.engineName,true);
501        }       
502        
503        public List<Map<String, Object>> desc(String schema, String tableName) throws Exception {
504                String schemaTableName = null;
505                if (CommonTools.isBlank(schema)) {
506                        schemaTableName = tableName;
507                } else {
508                        schemaTableName = String.format("%s.%s", schema, tableName);
509                }
510                return getCacheDriverExecutor(true).desc(schemaTableName);
511        }
512
513        public List<Map<String, Object>> showTables() throws Exception {
514                return showTables((String)null);
515        }
516
517        public List<Map<String, Object>> showTables(String schema) throws Exception {
518                if (schema == null) {
519                        return getCacheDriverExecutor(true).getAllTables();
520                } else {
521                        return getCacheDriverExecutor(true).getAllTables(schema);
522                }
523        }
524
525        public Map<String, Object> showColumnTypes(String tableName) throws Exception {
526                return getCacheDriverExecutor(true).getColumnTypes(tableName);
527
528        }
529
530        public Map<String, Object> showColumnClasses(String tableName) throws Exception {
531                return getCacheDriverExecutor(true).getColumnClasses(tableName);
532        }
533        
534        public String set(String key,Object value) {
535                consoleVariables.putAndReturnSlef(key,value);
536                return String.format("Set %s=%s", key, value);
537        }       
538
539        public String show(String key) {
540                Object value = consoleVariables.getString(key);
541                return String.format("Get %s=%s", key, value);
542        }
543
544        public String showAll() {
545                StringBuffer sbf = new StringBuffer();
546                Object[] keys = consoleVariables.keySet().toArray();
547                Arrays.sort(keys);
548                for (Object _key : keys) {
549                        String key = _key.toString();
550                        Object value = consoleVariables.get(key);
551                        sbf.append(String.format("Get %s=%s%s", key, value, System.lineSeparator()));
552                }
553                return sbf.toString();
554        }
555
556        public Boolean setAutoCommit(Boolean autoCommit) throws Exception {
557                if (cacheDriverExecutor == null) {
558                        return false;
559                } else {
560                        getCacheDriverExecutor(true).getConnection().setAutoCommit(autoCommit);
561                        return true;
562                }
563        }
564
565        public String genCreateTables(String schema, String sqlFilePath) {
566                try {
567                        StringBuffer errMsg = null;
568                        StringBuffer sql = new StringBuffer();
569                        List<Map<String, Object>> tables = getCacheDriverExecutor(true).getAllTables();
570                        File sqlFile = new File(sqlFilePath);
571                        if (tables.size() > 0) {
572                                if (sqlFile.exists())
573                                        sqlFile.delete();
574                        }
575                        for (Map<String, Object> table : tables) {
576                                try {
577                                        String tableSchema = (String) table.get("TABLE_SCHEMA");
578                                        String tableName = (String) table.get("TABLE_NAME");
579                                        if (CommonTools.isBlank(schema) && CommonTools.isBlank(tableSchema)) {
580                                                boolean append = sqlFile.exists();
581                                                StringBuffer ts = new StringBuffer(genCreateTable(null, tableName));
582                                                ts.append(System.lineSeparator());
583                                                ts.append(System.lineSeparator());
584                                                FileTools.write(sqlFile, ts.toString(), append);
585                                        }
586                                        if (!CommonTools.isBlank(schema) && !CommonTools.isBlank(tableSchema)) {
587                                                if (schema.equalsIgnoreCase(tableSchema)) {
588                                                        boolean append = sqlFile.exists();
589                                                        StringBuffer ts = new StringBuffer(genCreateTable(tableSchema, tableName));
590                                                        ts.append(System.lineSeparator());
591                                                        ts.append(System.lineSeparator());
592                                                        FileTools.write(sqlFile, ts.toString(), append);
593                                                }
594                                        }
595                                } catch (Exception ee) {
596                                        log.error(ee);
597                                        if (errMsg == null)
598                                                errMsg = new StringBuffer();
599
600                                        errMsg.append(ee.getMessage());
601                                        errMsg.append(System.lineSeparator());
602                                }
603                        }
604                        if (errMsg == null)
605                                return "Successfully";
606                        else
607                                return errMsg.toString();
608                } catch (Exception e) {
609                        log.error(e.getMessage(), e);
610                        return String.format("ERROR: %s", e.getMessage());
611                }
612        }
613
614        public String genCreateTable(String schema, String tableName) throws Exception {
615                String schemaTableName = null;
616                if (CommonTools.isBlank(schema)) {
617                        schemaTableName = tableName;
618                } else {
619                        schemaTableName = String.format("%s.%s", schema, tableName);
620                }
621                String commandEnd = consoleVariables.getString("CommandEnd", DEFAULT_CommandEnd);
622                StringBuffer sql = new StringBuffer(String.format("CREATE TABLE %s", quote(exportUpperOrLowerCase(tableName))));
623                sql.append(System.lineSeparator());
624                sql.append("(");
625                sql.append(System.lineSeparator());
626                List<Map<String, Object>> list = getCacheDriverExecutor(true).desc(schemaTableName);
627                int columnSize = list.size();
628                List<String> pkeys = new ArrayList<String>();
629                for (int i = 0; i < columnSize; i++) {
630                        Map<String, Object> tableInfo = list.get(i);
631                        Boolean isPrimaryKey = tableInfo.get("PRIMARY_KEY").equals("Y");
632
633                        if (!isPrimaryKey)
634                                continue;
635
636                        String name = (String) tableInfo.get("NAME");
637                        pkeys.add(quote(exportUpperOrLowerCase(name)));
638                }
639                String pkeysStr = null;
640                if (pkeys.size() > 0) {
641                        pkeysStr = String.format(",%sPRIMARY KEY (%s)", System.lineSeparator(), String.join(",", pkeys));
642                }
643                for (int i = 0; i < columnSize; i++) {
644                        Map<String, Object> tableInfo = list.get(i);
645                        String name = exportUpperOrLowerCase((String) tableInfo.get("NAME"));
646                        String javaType = (String) tableInfo.get("JAVA_TYPE");
647                        String dataType = (String) tableInfo.get("DATA_TYPE");
648                        Integer precision = (Integer) tableInfo.get("PRECISION");
649                        Boolean isAllowNullable = tableInfo.get("ALLOW_NULLABLE").equals("Y");
650                        String allowNullableStr = isAllowNullable ? "" : "NOT NULL";
651                        boolean isId = name.matches("^.*[\\_]{0,1}id$") && dataType.equals("CHAR") && precision == 16;
652                        String tableDataType = getDataType(isId, javaType, precision);
653                        sql.append(String.format("%s %s %s", quote(name), tableDataType, allowNullableStr).trim());
654                        if (i < columnSize - 1) {
655                                sql.append(",");
656                                sql.append(System.lineSeparator());
657                        }
658                }
659
660                if (pkeysStr != null)
661                        sql.append(pkeysStr);
662
663                sql.append(System.lineSeparator());
664                sql.append(")");
665                sql.append(commandEnd);
666                return sql.toString();
667        }
668
669        public String getDataType(boolean isId, String javaType, int precision) {
670                if (isId) {
671                        return "CHAR(16)";
672                }
673                if (javaType.equals(java.sql.Timestamp.class.getName())) {
674                        return String.format("DATETIME(%s)", 6);
675                } else if (javaType.equals(java.util.Date.class.getName())) {
676                        return String.format("DATETIME(%s)", 6);
677                } else if (javaType.equals(java.sql.Date.class.getName())) {
678                        return "DATE";
679                } else if (javaType.equals(java.sql.Time.class.getName())) {
680                        return "TIME";
681                } else if (javaType.equals(java.lang.Boolean.class.getName())) {
682                        return String.format("TINYINT(%s)", 1);
683                } else if (javaType.equals(java.lang.Byte.class.getName())) {
684                        return "INT";
685                } else if (javaType.equals(java.lang.Short.class.getName())) {
686                        return "INT";
687                } else if (javaType.equals(java.lang.Integer.class.getName())) {
688                        return "INT";
689                } else if (javaType.equals(java.lang.Long.class.getName())) {
690                        return "BIGINT";
691                } else if (javaType.equals(java.lang.Float.class.getName())) {
692                        return "FLOAT";
693                } else if (javaType.equals(java.lang.Double.class.getName())) {
694                        return "DOUBLE";
695                } else if (javaType.equals(java.math.BigDecimal.class.getName())) {
696                        return "DOUBLE";
697                } else if (javaType.equals(java.math.BigInteger.class.getName())) {
698                        return "BIGINT";
699                } else if (javaType.equals(java.lang.String.class.getName())) {
700                        if (precision <= 500) {
701                                return String.format("VARCHAR(%s)", precision);
702                        } else {
703                                return "TEXT";
704                        }
705                }
706                return "TEXT";
707        }
708
709        public static void setCacheApi(String apiClass) throws Exception {
710                Class clazz = Class.forName(apiClass.trim());
711                Constructor con = clazz.getConstructor(Boolean.class);
712                AbsCacheApi api = (AbsCacheApi) con.newInstance(true);
713                StoredCache.setApi(api);
714        }
715
716        public synchronized void reset() {
717                consoleVariables.putAndReturnSlef("QueryCursorStart", DEFAULT_QueryCursorStart);
718                consoleVariables.putAndReturnSlef("QueryMaxRows", DEFAULT_QueryMaxRows);
719                consoleVariables.putAndReturnSlef("AutoCommit", DEFAULT_AutoCommit);
720                consoleVariables.putAndReturnSlef("CommandEnd", DEFAULT_CommandEnd);
721                consoleVariables.putAndReturnSlef("CommandCancel", DEFAULT_CommandCancel);
722                consoleVariables.putAndReturnSlef("ColumnWidth", DEFAULT_ColumnWidth);
723                consoleVariables.putAndReturnSlef("ColumnCut", DEFAULT_ColumnCut);
724                consoleVariables.putAndReturnSlef("ShowResultHeader", DEFAULT_ShowResultHeader);
725                consoleVariables.putAndReturnSlef("ShowResultBody", DEFAULT_ShowResultBody);
726                consoleVariables.putAndReturnSlef("ShowResultFooter", DEFAULT_ShowResultFooter);
727                consoleVariables.putAndReturnSlef("DateTimeFormat", DEFAULT_DateTimeFormat);
728                consoleVariables.putAndReturnSlef("DateFormat", DEFAULT_DateFormat);
729                consoleVariables.putAndReturnSlef("TimeFormat", DEFAULT_TimeFormat);
730                consoleVariables.putAndReturnSlef("Name", DEFAULT_Name);
731                consoleVariables.putAndReturnSlef("WriteHistory", DEFAULT_WriteHistory);
732                consoleVariables.putAndReturnSlef("CommandHistory", DEFAULT_CommandHistory);
733                consoleVariables.putAndReturnSlef("ShowTaskLog", DEFAULT_ShowTaskLog);
734                consoleVariables.putAndReturnSlef("ExportMaxFileSize", DEFAULT_ExportMaxFileSize);
735                consoleVariables.putAndReturnSlef("ExportCursorStart", DEFAULT_ExportCursorStart);
736                consoleVariables.putAndReturnSlef("ExportMaxRows", DEFAULT_ExportMaxRows);
737                consoleVariables.putAndReturnSlef("ExportTimer", DEFAULT_ExportTimer);
738                consoleVariables.putAndReturnSlef("ExportOrderBy", DEFAULT_ExportOrderBy);
739                consoleVariables.putAndReturnSlef("ExportUpperOrLowerCase", DEFAULT_ExportUpperOrLowerCase);
740                consoleVariables.putAndReturnSlef("ExportSplit", DEFAULT_ExportSplit);
741                consoleVariables.putAndReturnSlef("ImportSplit", DEFAULT_ImportSplit);
742                consoleVariables.putAndReturnSlef("BatchSize", DEFAULT_BatchSize);
743                consoleVariables.putAndReturnSlef("Quote", DEFAULT_Quote);
744                consoleVariables.putAndReturnSlef("CallStoredProcedureFun", DEFAULT_CallStoredProcedureFun);
745                consoleVariables.putAndReturnSlef("ScriptEngine", DEFAULT_ScriptEngine);
746
747                consoleVariables.putAndReturnSlef("JdbcCipherAesKey", DEFAULT_Jdbc_Cipher_AesKey);
748                consoleVariables.putAndReturnSlef("ScriptCipherAesKey", DEFAULT_Script_Cipher_AesKey);
749                consoleVariables.putAndReturnSlef("ConfigCipherAesKey", DEFAULT_Config_Cipher_AesKey);
750        }
751
752        public String converToSqlFromMap(String schema, String tableName, List<String> columns) {
753                int columnSize = columns.size();
754                StringBuffer sql = new StringBuffer();
755                String fullTableName = schema == null ? tableName : String.format("%s.%s", schema, tableName);
756                sql.append(String.format("INSERT INTO %s ", quote(fullTableName)));
757                sql.append("(");
758                for (int i = 0; i < columnSize; i++) {
759                        String column = columns.get(i);
760                        sql.append(quote(column));
761                        if (i < columnSize - 1) {
762                                sql.append(",");
763                        }
764                }
765                sql.append(") VALUES (");
766                for (int i = 0; i < columnSize; i++) {
767                        String column = columns.get(i);
768                        sql.append(":" + column);
769                        if (i < columnSize - 1) {
770                                sql.append(",");
771                        }
772                }
773                sql.append(")");
774                return sql.toString();
775        }
776
777        public Object conver(String tableObjectFolder, String javaType, String encryptCell) throws Exception {
778                String _aesKey = consoleVariables.getString("JdbcCipherAesKey");
779
780                Object objectValue = null;
781
782                if (CommonTools.isBlank(encryptCell)) {
783                        return "";
784                }
785
786                boolean useEncrypt = !CommonTools.isBlank(_aesKey);
787
788                String cell = null;
789
790                if (useEncrypt) {
791                        byte[] by = Base64Tools.decode(encryptCell);
792                        cell = new String(CipherTools.AESDecrypt(_aesKey, by),BaseFile.CHARSET);
793                } else {
794                        cell = encryptCell;
795                }
796
797                if (cell.toUpperCase().equals("NULL")) {
798                        return null;
799                }
800
801                SimpleDateFormat dateTimeFormat = new SimpleDateFormat(consoleVariables.getString("DateTimeFormat"));
802                SimpleDateFormat dateFormat = new SimpleDateFormat(consoleVariables.getString("DateFormat"));
803                SimpleDateFormat timeFormat = new SimpleDateFormat(consoleVariables.getString("TimeFormat"));
804
805                if (javaType.equals(java.lang.String.class.getName())) {
806            objectValue = unescapeCsv(cell);
807                } else if (javaType.equals(java.util.Date.class.getName())) {
808                        objectValue = new java.util.Date(dateTimeFormat.parse(cell).getTime());
809                } else if (javaType.equals(java.sql.Date.class.getName())) {
810                        objectValue = new java.sql.Date(dateFormat.parse(cell).getTime());
811                } else if (javaType.equals(java.sql.Timestamp.class.getName())) {
812                        objectValue = new java.sql.Timestamp(dateTimeFormat.parse(cell).getTime());
813                } else if (javaType.equals(java.sql.Time.class.getName())) {
814                        objectValue = new java.sql.Time(dateTimeFormat.parse(cell).getTime());
815                } else if (javaType.equals(java.math.BigDecimal.class.getName())) {
816                        objectValue = Double.parseDouble(cell);
817                } else if (javaType.equals(java.math.BigInteger.class.getName())) {
818                        objectValue = Long.parseLong(cell);
819                } else if (javaType.equals(java.lang.Short.class.getName())) {
820                        objectValue = Short.parseShort(cell);
821                } else if (javaType.equals(java.lang.Integer.class.getName())) {
822                        objectValue = Integer.parseInt(cell);
823                } else if (javaType.equals(java.lang.Long.class.getName())) {
824                        objectValue = Long.parseLong(cell);
825                } else if (javaType.equals(java.lang.Float.class.getName())) {
826                        objectValue = Float.parseFloat(cell);
827                } else if (javaType.equals(java.lang.Double.class.getName())) {
828                        objectValue = Double.parseDouble(cell);
829                } else if (javaType.equals(java.sql.Clob.class.getName())) {
830                        String objPath = String.format("%s/%s", tableObjectFolder, cell);
831                        DataObject dob = new DataObject(_aesKey, objPath);
832                        objectValue = (byte[]) dob.getData();
833                } else if (javaType.equals(java.sql.Blob.class.getName())) {
834                        String objPath = String.format("%s/%s", tableObjectFolder, cell);
835                        DataObject dob = new DataObject(_aesKey, objPath);
836                        objectValue = (byte[]) dob.getData();
837                } else if (javaType.equals("[B")) {
838                        String objPath = String.format("%s/%s", tableObjectFolder, cell);
839                        DataObject dob = new DataObject(_aesKey, objPath);
840                        objectValue = (byte[]) dob.getData();
841                } else {
842                        //Not support the type.
843                        objectValue = null;
844                }
845                return objectValue;
846        }
847
848        public static String getJarPath() {
849                return CommonTools.getJarPath(ScriptConsole.class);
850        }
851        
852        public void exportTo(String _lastSelectCommand,File folder,String filePrefix) throws Exception {
853                exportTo(_lastSelectCommand,String.format("%s/%s",folder.getAbsolutePath(),filePrefix));
854        }       
855        
856        public void exportTo(File folder,String filePrefix) throws Exception {
857                exportTo(String.format("%s/%s",folder.getAbsolutePath(),filePrefix));
858        }       
859        
860        public synchronized void exportTo(String _lastSelectCommand,String file) throws Exception {
861            setLastSelectCommand(_lastSelectCommand);
862                Boolean showTaskLog = consoleVariables.getBoolean("ShowTaskLog", DEFAULT_ShowTaskLog);
863                if (CommonTools.isBlank(lastSelectCommand)) {
864                        throw new Exception("ERROR: Invalid blank select command");
865                }
866                Integer exportCursorStart = consoleVariables.getInteger("ExportCursorStart", DEFAULT_ExportCursorStart);
867                Integer exportMaxRows = consoleVariables.getInteger("ExportMaxRows", DEFAULT_ExportMaxRows);
868                CacheArray cacheArray = new CacheArray();
869                cacheArray.filter(getCacheArrayFilterForExport(showTaskLog, file));
870                getCacheDriverExecutor(true).find(exportCursorStart, exportMaxRows, lastSelectCommand, cacheArray);
871        }       
872
873        public synchronized void exportTo(String file) throws Exception {
874                Boolean showTaskLog = consoleVariables.getBoolean("ShowTaskLog", DEFAULT_ShowTaskLog);
875                if (CommonTools.isBlank(lastSelectCommand)) {
876                        throw new Exception("ERROR: Invalid blank select command");
877                }
878                Integer exportCursorStart = consoleVariables.getInteger("ExportCursorStart", DEFAULT_ExportCursorStart);
879                Integer exportMaxRows = consoleVariables.getInteger("ExportMaxRows", DEFAULT_ExportMaxRows);
880                CacheArray cacheArray = new CacheArray();
881                cacheArray.filter(getCacheArrayFilterForExport(showTaskLog, file));
882                getCacheDriverExecutor(true).find(exportCursorStart, exportMaxRows, lastSelectCommand, cacheArray);
883        }
884        
885        public CacheArrayFilter getCacheArrayFilterForExport(boolean showTaskLog, String file) {
886            return getCacheArrayFilterForExport(showTaskLog,file,null,null);
887        }
888        
889        public void exportTo(String _lastSelectCommand,File folder,String filePrefix,Runnable completedRun,Runnable terminatedRun) throws Exception {
890            setLastSelectCommand(_lastSelectCommand);
891                Boolean showTaskLog = consoleVariables.getBoolean("ShowTaskLog", DEFAULT_ShowTaskLog);
892                if (CommonTools.isBlank(lastSelectCommand)) {
893                        throw new Exception("ERROR: Invalid blank select command");
894                }
895                Integer exportCursorStart = consoleVariables.getInteger("ExportCursorStart", DEFAULT_ExportCursorStart);
896                Integer exportMaxRows = consoleVariables.getInteger("ExportMaxRows", DEFAULT_ExportMaxRows);
897                CacheArray cacheArray = new CacheArray();
898                String file = String.format("%s/%s",folder.getAbsolutePath(),filePrefix);
899                cacheArray.filter(getCacheArrayFilterForExport(showTaskLog, file,completedRun,terminatedRun));
900                getCacheDriverExecutor(true).find(exportCursorStart, exportMaxRows, lastSelectCommand, cacheArray);
901        }               
902
903        public CacheArrayFilter getCacheArrayFilterForExport(boolean showTaskLog, String file,Runnable completedRun,Runnable terminatedRun) {
904                Integer exportMaxFileSize = consoleVariables.getInteger("ExportMaxFileSize", DEFAULT_ExportMaxFileSize);
905                Long exportTimer = consoleVariables.getLong("ExportTimer", DEFAULT_ExportTimer);
906                String exportSplit = consoleVariables.getString("ExportSplit", DEFAULT_ExportSplit);
907                final java.util.Date beginTime = new java.util.Date();
908                
909                return new CacheArrayFilter(0L,exportTimer) {
910                        int outIndex = 0;
911                        int exportedIndex = 0;
912                        DiskFile csvFile = null;
913                        File outFile = new File(file);
914                        String outFolder = outFile.getParent();
915                        String outFileName = exportUpperOrLowerCase(outFile.getName().replaceFirst("\\..*", ""));
916                        final List<String> columns = new ArrayList<String>();
917                        final StringBuffer header = new StringBuffer();
918                        
919                        @Override
920                        public void executeBatch(Integer index,List batch) {
921                if (showTaskLog) {
922                                System.out.println(String.format("Exporting table %s (%s -> %s).", outFileName,index,batch.size()));
923                        }
924                        
925                            for(Object o : batch){
926                                try {
927                                        String tableObjectFolder = String.format("%s/%s_objects", outFolder, outFileName);
928                                        Map<String, Object> cacheRow = (Map<String, Object>) o;
929                                        if (csvFile == null) {
930                                                String outIndexFormat = String.format("%09d", outIndex);
931                                                csvFile = new DiskFile(String.format("%s/%s.%s.csv", outFolder, outFileName, outIndexFormat));
932                                                if (csvFile.exists()) {
933                                                        csvFile.delete();
934                                                }
935                                                if (showTaskLog) {
936                                                        System.out.println(String.format("Exporting table %s", outFileName));
937                                                }
938                                                columns.addAll(cacheRow.keySet());
939                                                int columsSize = columns.size();
940                                                for (int i = 0; i < columsSize; i++) {
941                                                        header.append(exportUpperOrLowerCase(columns.get(i)));
942                                                        if (i < columsSize - 1)
943                                                                header.append(exportSplit);
944                                                }
945                                                header.append(System.lineSeparator());
946                                                csvFile.manualOpen(true); 
947                                                csvFile.manualWrite(header.toString());
948                                        }
949                                        if (index >= 0) {
950                                                StringBuffer cells = new StringBuffer();
951                                                int columsSize = columns.size();
952                                                for (int j = 0; j < columsSize; j++) {
953                                                        String column = columns.get(j);
954                                                        Object objValue = cacheRow.get(column);
955                                                        String value = formatForExport(tableObjectFolder, objValue);
956                                                        cells.append(value);
957                                                        if (j < columsSize - 1)
958                                                                cells.append(exportSplit);
959                                                }
960                                                cells.append(System.lineSeparator());
961                                                Path path = Paths.get(csvFile.getPath());
962                                                long sizeInBytes = Files.size(path);
963                                                long sizeInMb = sizeInBytes / (1024 * 1024);
964                                                if (sizeInMb >= exportMaxFileSize) {
965                                                        outIndex++;
966                                                        String outIndexFormat = String.format("%09d", outIndex);
967                                                        
968                                                        csvFile.manualClose();
969    
970                                                        csvFile = new DiskFile(String.format("%s/%s.%s.csv", outFolder, outFileName, outIndexFormat));
971                                                        if (csvFile.exists()) {
972                                                                csvFile.delete();
973                                                        }
974                                                        
975                                                        csvFile.manualOpen(true); 
976                                                        csvFile.manualWrite(header.toString());
977                                                }
978                                                csvFile.manualWrite(cells.toString());
979                                        }
980    
981                                } catch (Exception e) {
982                                        log.error(e.getMessage(), e);
983                                }
984                            }
985                        }
986
987                        @Override
988                        public void execute(Integer index, Object o) {
989                            
990                        }
991
992                        @Override
993                        public void completed(Integer size) {
994                                try {
995                                        String outIndexFormat = String.format("%09d", 0);
996                                    if(csvFile != null){
997                                        csvFile.manualClose();
998                                    }
999                                        if (csvFile == null) {
1000                                            csvFile = new DiskFile(String.format("%s/%s.%s.csv", outFolder, outFileName, outIndexFormat));
1001                                                csvFile.write("", false);
1002                                        }
1003                                } catch (Exception e) {
1004                                        log.error(e.getMessage(), e);
1005                                }
1006                                if (showTaskLog) {
1007                                        long timeCostMs = new java.util.Date().getTime() - beginTime.getTime();
1008                                        System.out
1009                                                        .println(String.format("Table %s %s rows exported (%sms)", outFileName, size, timeCostMs));
1010                                }
1011                                
1012                                if(completedRun != null) completedRun.run();
1013                        }
1014                        
1015                        @Override
1016                        public void terminated(){
1017                            if(csvFile != null){
1018                                try{
1019                                        csvFile.manualClose();
1020                                }catch(Exception e){
1021                                    log.error(e.getMessage(), e);
1022                                }
1023                                }
1024                                
1025                                if(terminatedRun != null) terminatedRun.run();
1026                        }
1027                };
1028        }
1029
1030        public String format(Object objValue) {
1031                String format = "%" + consoleVariables.getInteger("ColumnWidth", DEFAULT_ColumnWidth) + "s";
1032                String value = formatObjectValue(false, false, objValue, String.format("%s/tmp", getJarPath()));
1033                return String.format(format, columnCut(value));
1034        }
1035
1036        public String formatForExport(Object objValue) {
1037                return formatObjectValue(false, true, objValue, String.format("%s/tmp", getJarPath()));
1038        }
1039
1040        public String formatForExport(String tableObjectFolder, Object objValue) {
1041                String _aesKey = consoleVariables.getString("JdbcCipherAesKey");
1042                boolean useEncrypt = !CommonTools.isBlank(_aesKey);
1043                return formatObjectValue(useEncrypt, true, objValue, tableObjectFolder);
1044        }
1045
1046        public String formatObjectValue(boolean useEncrypt, boolean single, Object objValue,
1047                        String tableObjectFolder) {
1048                SimpleDateFormat dateTimeFormat = new SimpleDateFormat(consoleVariables.getString("DateTimeFormat"));
1049                SimpleDateFormat dateFormat = new SimpleDateFormat(consoleVariables.getString("DateFormat"));
1050                SimpleDateFormat timeFormat = new SimpleDateFormat(consoleVariables.getString("TimeFormat"));
1051                String _aesKey = consoleVariables.getString("JdbcCipherAesKey");
1052                String value = null;
1053                if (objValue == null) {
1054                        value = "NULL";
1055                } else if (objValue instanceof byte[]) {
1056                        try {
1057                                String mappingName = String.format("object_%s", CommonTools.generateId(32));
1058                                byte[] by = (byte[]) objValue;
1059                                String objPath = String.format("%s/%s", tableObjectFolder, mappingName);
1060                                DataObject dob = new DataObject(_aesKey, objPath);
1061                                dob.setObject(by);
1062                                value = mappingName;
1063                        } catch (Exception e) {
1064                                log.error(e.getMessage(), e);
1065                                return null;
1066                        }
1067                } else if (objValue instanceof java.sql.Clob) {
1068                        try {
1069                                String mappingName = String.format("object_%s", CommonTools.generateId(32));
1070                                byte[] by = toByteArray((Clob) objValue);
1071                                String objPath = String.format("%s/%s", tableObjectFolder, mappingName);
1072                                DataObject dob = new DataObject(_aesKey, objPath);
1073                                dob.setObject(by);
1074                                value = mappingName;
1075                        } catch (Exception e) {
1076                                log.error(e.getMessage(), e);
1077                                return null;
1078                        }
1079                } else if (objValue instanceof java.sql.Blob) {
1080                        try {
1081                                String mappingName = String.format("object_%s", CommonTools.generateId(32));
1082                                byte[] by = toByteArray((Blob) objValue);
1083                                String objPath = String.format("%s/%s", tableObjectFolder, mappingName);
1084                                DataObject dob = new DataObject(_aesKey, objPath);
1085                                dob.setObject(by);
1086                                value = mappingName;
1087                        } catch (Exception e) {
1088                                log.error(e.getMessage(), e);
1089                                return null;
1090                        }
1091                } else if (objValue instanceof java.sql.Timestamp) {
1092                        value = dateTimeFormat.format((java.sql.Timestamp) objValue);
1093                } else if (objValue instanceof java.util.Date) {
1094                        value = dateTimeFormat.format((java.util.Date) objValue);
1095                } else if (objValue instanceof java.sql.Date) {
1096                        value = dateFormat.format((java.sql.Date) objValue);
1097                } else if (objValue instanceof java.sql.Time) {
1098                        value = timeFormat.format((java.sql.Time) objValue);
1099                } else if (objValue instanceof Boolean) {
1100                        value = objValue.equals(true) ? "1" : "0";
1101                } else if (objValue instanceof String) {
1102                        if (single)
1103                                value = toSingle((String) objValue);
1104                        else
1105                                value = (String) objValue;
1106                } else {
1107                        value = objValue + "";
1108                }
1109                if (!useEncrypt) {
1110                        return value;
1111                }
1112                try {
1113                        byte[] encData = CipherTools.AESEncrypt(_aesKey, value.getBytes(BaseFile.CHARSET));
1114                        return new String(Base64Tools.encode(encData));
1115                } catch (Exception e) {
1116                        log.error(e.getMessage(), e);
1117                }
1118                return null;
1119        }
1120
1121        public byte[] toByteArray(Blob blobValue) {
1122                try {
1123                        return blobValue.getBinaryStream().readAllBytes();
1124                } catch (Exception e) {
1125                        log.error(e.getMessage(), e);
1126                        return null;
1127                }
1128        }
1129
1130        public byte[] toByteArray(Clob clobValue) {
1131                try {
1132                        int length = Long.bitCount(clobValue.length());
1133                        byte[] array = new byte[length];
1134                        InputStream in = clobValue.getAsciiStream();
1135                        int offset = 0;
1136                        int n;
1137                        do
1138                                n = in.read(array, offset, length - offset);
1139                        while (n != -1);
1140                        return array;
1141                } catch (Exception e) {
1142                        log.error(e.getMessage(), e);
1143                        return null;
1144                }
1145        }
1146
1147        public String columnCut(String strValue) {
1148                if (strValue == null)
1149                        strValue = "NULL";
1150
1151                Integer columnCut = consoleVariables.getInteger("ColumnCut", DEFAULT_ColumnCut);
1152                if (columnCut > 0) {
1153                        if (strValue.length() > columnCut) {
1154                                strValue = strValue.substring(0, columnCut);
1155                        }
1156                }
1157                return strValue;
1158        }
1159
1160        public String toSingle(String text) {
1161                if (text == null)
1162                        return null;
1163
1164        return escapeCsv(text);
1165        }
1166
1167        public void clear() {
1168                clear(true);
1169        }
1170
1171        private void clear(Boolean enableSystemOut) {
1172                if (enableSystemOut){
1173                    try{
1174                String os = System.getProperty("os.name").toUpperCase();
1175                if (os.contains("WINDOWS")) {
1176                    new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
1177                } else { 
1178                    new ProcessBuilder("clear").inheritIO().start().waitFor();
1179                }
1180                    }catch(Exception e){
1181                        System.out.println(error(e));
1182                        log.error(e.getMessage(), e);
1183                System.out.print("\033[H\033[2J");
1184                System.out.flush();
1185                    }
1186                }
1187        }
1188
1189        public boolean open() {
1190                return open(true);
1191        }
1192
1193        public void close() {
1194                try {
1195                        close(true);
1196                } catch (SQLException e) {
1197                        log.error(e.getMessage(), e);
1198                        System.out.println(error(e));
1199                }
1200        }
1201
1202        public void commit() {
1203                try {
1204                        commit(true);
1205                } catch (SQLException e) {
1206                        log.error(e.getMessage(), e);
1207                        System.out.println(error(e));
1208                }
1209        }
1210
1211        public void rollback() {
1212                try {
1213                        rollback(true);
1214                } catch (SQLException e) {
1215                        log.error(e.getMessage(), e);
1216                        System.out.println(error(e));
1217                }
1218        }
1219
1220        public void abort() {
1221                try {
1222                        abort(true);
1223                } catch (SQLException e) {
1224                        log.error(e.getMessage(), e);
1225                        System.out.println(error(e));
1226                }
1227        }
1228
1229        private void abort(Boolean enableSystemOut) throws SQLException {
1230                if (cacheDriverExecutor == null) {
1231                        if (enableSystemOut)
1232                                System.out.println("ERROR: Connection is null");
1233                } else {
1234                        cacheDriverExecutor.abort();
1235                        cacheDriverExecutor = null;
1236                        if (enableSystemOut)
1237                                System.out.println("Aborted connection");
1238                }
1239        }
1240
1241        private void rollback(Boolean enableSystemOut) throws SQLException {
1242                if (cacheDriverExecutor == null) {
1243                        if (enableSystemOut)
1244                                System.out.println("ERROR: Failed rollback, connection is null.");
1245                } else {
1246                        cacheDriverExecutor.rollback();
1247                        if (enableSystemOut)
1248                                System.out.println("Rollback completed");
1249                }
1250        }
1251
1252        private void commit(Boolean enableSystemOut) throws SQLException {
1253                if (cacheDriverExecutor == null) {
1254                        if (enableSystemOut)
1255                                System.out.println("ERROR: Failed commit, connection is null.");
1256                } else {
1257                        cacheDriverExecutor.commit();
1258                        if (enableSystemOut)
1259                                System.out.println("Commit completed");
1260                }
1261        }
1262
1263        private void close(Boolean enableSystemOut) throws SQLException {
1264                if (cacheDriverExecutor == null) {
1265                        if (enableSystemOut)
1266                                System.out.println("ERROR: Connection is null");
1267                } else {
1268                        cacheDriverExecutor.close();
1269                        cacheDriverExecutor = null;
1270                        if (enableSystemOut)
1271                                System.out.println("Closed connection");
1272                }
1273        }
1274
1275        private boolean open(Boolean enableSystemOut) {
1276                if (cacheDriverExecutor == null || cacheDriverExecutor.isClosed()) {
1277                        firstOpen = false;
1278                        try {
1279                            
1280                            if(ScriptConsole.datasource == null) ScriptConsole.datasource = getDataSource(); 
1281                            
1282                                Connection connection = ScriptConsole.datasource.getConnection();
1283                                connection.setAutoCommit(consoleVariables.getBoolean("AutoCommit", DEFAULT_AutoCommit));
1284                                cacheDriverExecutor = new CacheDriverExecutor(connection);
1285                                if (enableSystemOut)
1286                                        System.out.println(String.format("Connected (AutoCommit=%s)",connection.getAutoCommit()+""));
1287
1288                                return true;
1289                        } catch (Exception e) {
1290                                log.error(e.getMessage(), e);
1291                                System.out.println(e.getMessage());
1292                                if (enableSystemOut)
1293                                        System.out.println("Disconnected");
1294
1295                                return false;
1296                        }
1297                }
1298
1299                return true;
1300        }
1301
1302        public Object executeBatch(String batchFile) throws Exception {
1303            if(isUseScriptEnv()){
1304                    return eval(batchFile);
1305            }
1306            if(isUseJdbcEnv()){
1307                    return executeJdbcBatch(batchFile);
1308            }
1309            if(isUseCmdEnv()){
1310                    return executeCmdBatch(batchFile);
1311            }
1312            return null;
1313        }
1314        
1315        protected String executeCmdBatch(String _batchFile) throws Exception {
1316                try {
1317                    File batchFile = new File(_batchFile);
1318                        if (!batchFile.exists()) {
1319                                return String.format("ERROR: Batch file not found '%s'", batchFile);
1320                        }
1321                        String commandLines = decryptScript(batchFile);
1322                        if (!CommonTools.isBlank(commandLines)) {
1323                                String commandEnd = consoleVariables.getString("CommandEnd", DEFAULT_CommandEnd);
1324                                List<String> commandList = Arrays.asList(commandLines.split(commandEnd + "[^\\S]*\n"));
1325                                int row = 0;
1326                                for (String cl : commandList) {
1327                                        if (!CommonTools.isBlank(cl)) {
1328                                                String command = cl.trim();
1329                                                if (command.indexOf("#") != 0) {
1330                                                        System.out.println(
1331                                                                        String.format("%s) %s",row,command));
1332                                                                        
1333                                                        executeViaCmd(true, command);
1334                                                }
1335                                        }
1336                                        row++;
1337                                }
1338                        }
1339                        return null;
1340                } catch (Exception e) {
1341                        log.error(e.getMessage(), e);
1342                        return e.getMessage();
1343                }
1344        }       
1345        
1346        protected String executeJdbcBatch(String _batchFile) throws Exception {
1347                try {
1348                    File batchFile = new File(_batchFile);
1349                        if (!batchFile.exists()) {
1350                                return String.format("ERROR: Batch file not found '%s'", batchFile);
1351                        }
1352                        String commandLines = decryptScript(batchFile);
1353                        if (!CommonTools.isBlank(commandLines)) {
1354                                String commandEnd = consoleVariables.getString("CommandEnd", DEFAULT_CommandEnd);
1355                                List<String> commandList = Arrays.asList(commandLines.split(commandEnd + "[^\\S]*\n"));
1356                                int row = 0;
1357                                for (String cl : commandList) {
1358                                        if (!CommonTools.isBlank(cl)) {
1359                                                String command = cl.trim();
1360                                                if (command.indexOf("-") != 0) {
1361                                                        System.out.println(
1362                                                                        String.format("%s) %s",row,command));
1363                                                                        
1364                                                        executeViaJdbc(true, command);
1365                                                }
1366                                        }
1367                                        row++;
1368                                }
1369                        }
1370                        return null;
1371                } catch (Exception e) {
1372                        log.error(e.getMessage(), e);
1373                        return e.getMessage();
1374                }
1375        }               
1376
1377        public Object evalScript(String script) throws Exception {
1378                return jsPlusContext.evalScript(script);
1379        }
1380        
1381        public boolean executeViaGhost(String commands){
1382            return executeViaGhost(true,commands);
1383        }       
1384        
1385        public boolean executeViaGhost(boolean enableSystemOut,String commands){
1386            String commandEnd = consoleVariables.getString("CommandEnd",DEFAULT_CommandEnd);
1387            String executeCommand = commands.toString().replaceFirst("(" + commandEnd + "){1,}[\s]*$","").trim();
1388            
1389                if (executeCommand.trim().equals("")) {
1390                        System.out.println("ERROR: Invalid blank command");
1391                        return false;
1392                }
1393                
1394                Boolean writeHistory = consoleVariables.getBoolean("WriteHistory",DEFAULT_WriteHistory);
1395        String commandHistory = consoleVariables.getString("CommandHistory", DEFAULT_CommandHistory);
1396                
1397            boolean isCancel = isCommandCancel(executeCommand);
1398            
1399            if(isCancel) return true;
1400
1401            try{
1402                log.debug(executeCommand);
1403                
1404                    if(writeHistory && executeCommand.indexOf(commandHistory) != 0){
1405                        if(!CommonTools.isBlank(executeCommand))
1406                            addHistory(executeCommand.trim());
1407                    }           
1408               
1409                if (executeCommand.toUpperCase().equals("EXIT")) {
1410                                if(cacheDriverExecutor != null){
1411                    if(!cacheDriverExecutor.isClosed()){
1412                        System.out.println("ERROR: The connection is in use, please close the connection first.");
1413                    }else{
1414                        System.exit(0);
1415                        return true;
1416                    }
1417                            }
1418                            if(cacheDriverExecutor == null)
1419                                    System.exit(0);
1420                                    
1421                                return true;
1422                }
1423                
1424                if(executeCommand.indexOf(commandHistory) == 0){
1425                            String hiscmd = executeCommand.replaceFirst("^" + commandHistory,"");
1426                        showHistory(hiscmd);
1427                    }else if(executeCommand.toUpperCase().equals("CLEAR")){
1428                        clear(true);
1429                    }else if(executeCommand.toUpperCase().equals("JDBC")){
1430                setUseJdbcEnv();
1431                consoleVariables.putAndReturnSlef("CommandEnd",";");
1432                consoleVariables.putAndReturnSlef("Name","jdbc");
1433                        System.out.println("Changed CommandEnd to ';'");
1434                }else if(executeCommand.toUpperCase().equals("SCRIPT")){
1435                setUseScriptEnv();
1436                consoleVariables.putAndReturnSlef("CommandEnd","/");
1437                set("Name",displayEngineName);
1438                        System.out.println("Changed CommandEnd to '/'");
1439                } else if (executeCommand.matches(CONSOLE_VAR_REGEX)){
1440                            String[] keyValue = executeCommand.split("=",2);
1441                            if(keyValue.length == 2){
1442                                String key = keyValue[0].trim().replaceFirst("^Console\\.","");
1443                                String value = keyValue[1].trim();
1444                                consoleVariables.putAndReturnSlef(key,value);
1445                                if(enableSystemOut) System.out.println(String.format("Successfully Console.%s=%s",key,value));
1446                            }else{
1447                                if(enableSystemOut) System.out.println("ERROR: Invalid console variable");
1448                            }
1449                        } else if (executeCommand.matches(CONSOLE_FUN_REGEX)){
1450                    Pattern pattern = Pattern.compile(CONSOLE_FUN_REGEX);
1451                Matcher matcher = pattern.matcher(executeCommand);
1452                if(matcher.find()){
1453                    String fun = matcher.group(2);
1454                    String paramsStr = matcher.group(3).trim();
1455                    List<String> params = new ArrayList<String>();
1456                    if(!CommonTools.isBlank(paramsStr)){
1457                        params = Arrays.asList(paramsStr.split(","));
1458                    }
1459                    try{
1460                        Method method = CmdConsole.class.getMethod(fun,List.class);
1461                        Object msg = method.invoke(this,params);
1462                        if(enableSystemOut) {
1463                            if(msg != null){
1464                                System.out.println(msg.toString());
1465                            }
1466                        }
1467                    }catch(Exception e){
1468                        log.error(e.getMessage(),e);
1469                        if(enableSystemOut){ 
1470                            System.out.println(String.format("ERROR: Invalid method '%s'",fun));
1471                            System.out.println(error(e));
1472                        }
1473                    }
1474                }
1475                        }else{
1476                   if(ghostConsole == null){
1477                       ghostConsole = new GhostConsole(this,consoleVariables.getString("GhostName","DefaultGhost"));
1478                       ghostConsole.detect();
1479                   }
1480                   ghostConsole.submit(executeCommand);
1481                }
1482            }catch(Exception e){
1483            System.out.println(error(e));
1484            log.info(executeCommand);
1485            log.error(e.getMessage(),e);
1486            if(writeHistory && executeCommand.indexOf(commandHistory) != 0){
1487                addHistory(" <INVALID");
1488            }
1489            return false;
1490                }finally {
1491                if(writeHistory && executeCommand.indexOf(commandHistory) != 0){
1492                addHistory(System.lineSeparator());
1493                }
1494                }
1495                return true;
1496        }       
1497        
1498        public boolean executeViaCmd(boolean enableSystemOut,String commands){
1499            return executeViaCmd(enableSystemOut,commands,null,null);
1500        }
1501        
1502        public boolean executeViaCmd(boolean enableSystemOut,String commands,Runnable successfullyRun,Runnable faiiledRun){
1503            String commandEnd = consoleVariables.getString("CommandEnd",DEFAULT_CommandEnd);
1504            String executeCommand = commands.toString().replaceFirst("(" + commandEnd + "){1,}[\s]*$","").trim();
1505            
1506                if (executeCommand.trim().equals("")) {
1507                        System.out.println("ERROR: Invalid blank command");
1508                        return false;
1509                }
1510                
1511                Boolean writeHistory = consoleVariables.getBoolean("WriteHistory",DEFAULT_WriteHistory);
1512        String commandHistory = consoleVariables.getString("CommandHistory", DEFAULT_CommandHistory);
1513                
1514            boolean isCancel = isCommandCancel(executeCommand);
1515            
1516            if(isCancel) return true;
1517
1518            try{
1519                log.debug(executeCommand);
1520                
1521                    if(writeHistory && executeCommand.indexOf(commandHistory) != 0){
1522                        if(!CommonTools.isBlank(executeCommand))
1523                            addHistory(executeCommand.trim());
1524                    }           
1525               
1526                if (executeCommand.toUpperCase().equals("EXIT")) {
1527                                if(cacheDriverExecutor != null){
1528                    if(!cacheDriverExecutor.isClosed()){
1529                        System.out.println("ERROR: The connection is in use, please close the connection first.");
1530                    }else{
1531                        System.exit(0);
1532                        return true;
1533                    }
1534                            }
1535                            if(cacheDriverExecutor == null)
1536                                    System.exit(0);
1537                                    
1538                                return true;
1539                }
1540                
1541                if(executeCommand.indexOf(commandHistory) == 0){
1542                            String hiscmd = executeCommand.replaceFirst("^" + commandHistory,"");
1543                        showHistory(hiscmd);
1544                    }else if(executeCommand.toUpperCase().equals("CLEAR")){
1545                        clear(true);
1546                    }else if(executeCommand.toUpperCase().equals("JDBC")){
1547                setUseJdbcEnv();
1548                consoleVariables.putAndReturnSlef("CommandEnd",";");
1549                consoleVariables.putAndReturnSlef("Name","jdbc");
1550                if(enableSystemOut) {
1551                            System.out.println("Changed CommandEnd to ';'");
1552                }
1553                }else if(executeCommand.toUpperCase().equals("SCRIPT")){
1554                setUseScriptEnv();
1555                consoleVariables.putAndReturnSlef("CommandEnd","/");
1556                set("Name",displayEngineName);
1557                if(enableSystemOut) {
1558                            System.out.println("Changed CommandEnd to '/'");
1559                }
1560                }else if(executeCommand.toUpperCase().equals("GHOST")){
1561                setUseGhostEnv();
1562                consoleVariables.putAndReturnSlef("CommandEnd","/");
1563                set("Name","ghost");
1564                if(enableSystemOut) {
1565                            System.out.println("Changed CommandEnd to '/'");
1566                }
1567                } else if (executeCommand.matches(CONSOLE_VAR_REGEX)){
1568                            String[] keyValue = executeCommand.split("=",2);
1569                            if(keyValue.length == 2){
1570                                String key = keyValue[0].trim().replaceFirst("^Console\\.","");
1571                                String value = keyValue[1].trim();
1572                                consoleVariables.putAndReturnSlef(key,value);
1573                                if(enableSystemOut) System.out.println(String.format("Successfully Console.%s=%s",key,value));
1574                            }else{
1575                                if(enableSystemOut) System.out.println("ERROR: Invalid console variable");
1576                            }
1577                        } else if (executeCommand.matches(CONSOLE_FUN_REGEX)){
1578                    Pattern pattern = Pattern.compile(CONSOLE_FUN_REGEX);
1579                Matcher matcher = pattern.matcher(executeCommand);
1580                if(matcher.find()){
1581                    String fun = matcher.group(2);
1582                    String paramsStr = matcher.group(3).trim();
1583                    List<String> params = new ArrayList<String>();
1584                    if(!CommonTools.isBlank(paramsStr)){
1585                        params = Arrays.asList(paramsStr.split(","));
1586                    }
1587                    try{
1588                        Method method = CmdConsole.class.getMethod(fun,List.class);
1589                        Object msg = method.invoke(this,params);
1590                        if(enableSystemOut) {
1591                            if(msg != null){
1592                                System.out.println(msg.toString());
1593                            }
1594                        }
1595                    }catch(Exception e){
1596                        log.error(e.getMessage(),e);
1597                        if(enableSystemOut){ 
1598                            System.out.println(String.format("ERROR: Invalid method '%s'",fun));
1599                            System.out.println(error(e));
1600                        }
1601                    }
1602                }
1603                        }else{
1604                   if(cmdConsole == null){
1605                       cmdConsole = new CmdConsole(enableSystemOut);
1606                   }
1607                   Process process = cmdConsole.submit(executeCommand,successfullyRun,faiiledRun);
1608                   if(process != null){
1609                       System.out.println(String.format("Current PID '%s'.",process.pid()));
1610                   }
1611                }
1612            }catch(Exception e){
1613            System.out.println(error(e));
1614            log.error(executeCommand);
1615            log.error(e.getMessage(),e);
1616            if(writeHistory && executeCommand.indexOf(commandHistory) != 0){
1617                addHistory(" <INVALID");
1618            }
1619            return false;
1620                }finally {
1621                if(writeHistory && executeCommand.indexOf(commandHistory) != 0){
1622                addHistory(System.lineSeparator());
1623                }
1624                }
1625                return true;
1626        }
1627
1628        public boolean executeViaScript(String commands){
1629            String commandEnd = consoleVariables.getString("CommandEnd",DEFAULT_CommandEnd);
1630            String executeCommand = commands.toString().replaceFirst("(" + commandEnd + "){1,}[\s]*$","").trim();
1631            
1632                if (executeCommand.trim().equals("")) {
1633                        System.out.println("ERROR: Invalid blank command");
1634                        return false;
1635                }
1636                
1637                Boolean writeHistory = consoleVariables.getBoolean("WriteHistory",DEFAULT_WriteHistory);
1638        String commandHistory = consoleVariables.getString("CommandHistory", DEFAULT_CommandHistory);
1639                
1640            boolean isCancel = isCommandCancel(executeCommand);
1641            
1642            if(isCancel) return true;
1643
1644            try{
1645                log.debug(executeCommand);
1646                
1647                    if(writeHistory && executeCommand.indexOf(commandHistory) != 0){
1648                        if(!CommonTools.isBlank(executeCommand))
1649                            addHistory(executeCommand.trim());
1650                    }           
1651               
1652                if (executeCommand.toUpperCase().equals("EXIT")) {
1653                                if(cacheDriverExecutor != null){
1654                    if(!cacheDriverExecutor.isClosed()){
1655                        System.out.println("ERROR: The connection is in use, please close the connection first.");
1656                    }else{
1657                        System.exit(0);
1658                        return true;
1659                    }
1660                            }
1661                            if(cacheDriverExecutor == null)
1662                                    System.exit(0);
1663                                    
1664                                return true;
1665                }
1666                
1667                if(executeCommand.indexOf(commandHistory) == 0){
1668                            String hiscmd = executeCommand.replaceFirst("^" + commandHistory,"");
1669                        showHistory(hiscmd);
1670                    }else if(executeCommand.toUpperCase().equals("CLEAR")){
1671                        clear(true);
1672                    }else if(executeCommand.toUpperCase().equals("JDBC")){
1673                setUseJdbcEnv();
1674                consoleVariables.putAndReturnSlef("CommandEnd",";");
1675                consoleVariables.putAndReturnSlef("Name","jdbc");
1676                        System.out.println("Changed CommandEnd to ';'");
1677                }else if(executeCommand.toUpperCase().equals("CMD")){
1678                setUseCmdEnv();
1679                consoleVariables.putAndReturnSlef("CommandEnd","/");
1680                consoleVariables.putAndReturnSlef("Name","cmd");
1681                        System.out.println("Changed CommandEnd to '/'");
1682                }else if(executeCommand.toUpperCase().equals("GHOST")){
1683                setUseGhostEnv();
1684                consoleVariables.putAndReturnSlef("CommandEnd","/");
1685                consoleVariables.putAndReturnSlef("Name","ghost");
1686                        System.out.println("Changed CommandEnd to '/'");
1687                }else{
1688                        if(jsPlusContext == null){
1689                            initScriptEngineManager();
1690                        }
1691                    evalScript(executeCommand);
1692                }
1693            }catch(Exception e){
1694            System.out.println(error(e));
1695            log.debug(executeCommand);
1696            log.error(e.getMessage(),e);
1697            if(writeHistory && executeCommand.indexOf(commandHistory) != 0){
1698                addHistory(" <INVALID");
1699            }
1700            return false;
1701                }finally {
1702                if(writeHistory && executeCommand.indexOf(commandHistory) != 0){
1703                addHistory(System.lineSeparator());
1704                }
1705                }
1706                return true;
1707    }
1708    
1709        public boolean execute(String commands) {
1710            if(isUseScriptEnv()) return executeViaScript(commands);
1711            
1712            if(isUseJdbcEnv()) return executeViaJdbc(commands);
1713            
1714            if(isUseCmdEnv()) return executeViaCmd(commands);
1715            
1716            return false;
1717        }   
1718
1719        public boolean executeViaJdbc(String commands) {
1720                return executeViaJdbc(true, commands);
1721        }
1722        
1723        public boolean executeViaCmd(String commands) {
1724                return executeViaCmd(true, commands);
1725        }
1726        
1727        public boolean executeViaCmd(Boolean enableSystemOut,String commands,Runnable successfullyRun,Runnable faiiledRun) {
1728                return executeViaCmd(enableSystemOut, commands,successfullyRun,faiiledRun);
1729        }       
1730
1731        public boolean executeViaJdbc(Boolean enableSystemOut,String commands) {
1732            String commandEnd = consoleVariables.getString("CommandEnd",DEFAULT_CommandEnd);
1733            String executeCommand = commands.toString().replaceFirst("(" + commandEnd + "){1,}[\s]*$","").trim();
1734            
1735                if (executeCommand.trim().equals("")) {
1736                        System.out.println("ERROR: Invalid blank command");
1737                        return false;
1738                }
1739                
1740                boolean isCancel = isCommandCancel(executeCommand);
1741            
1742            if(isCancel) return true;
1743            
1744        Boolean writeHistory = consoleVariables.getBoolean("WriteHistory",DEFAULT_WriteHistory);
1745        String commandHistory = consoleVariables.getString("CommandHistory", DEFAULT_CommandHistory);
1746                try {
1747                    
1748                    log.info(executeCommand);
1749
1750                    if(writeHistory && enableSystemOut && executeCommand.indexOf(commandHistory) != 0){
1751                        if(!CommonTools.isBlank(executeCommand))
1752                            addHistory(executeCommand.trim());
1753                    }
1754                    
1755                        if (executeCommand.toUpperCase().equals("EXIT")) {
1756                                if(cacheDriverExecutor != null){
1757                    if(!cacheDriverExecutor.isClosed()){
1758                        System.out.println("ERROR: The connection is in use, please close the connection first.");
1759                    }
1760                                }
1761                                
1762                                if(cacheDriverExecutor == null)
1763                                    System.exit(0);
1764                                    
1765                                return true;
1766                        }  
1767                        
1768                        
1769            if(executeCommand.toUpperCase().equals("SCRIPT")){
1770                        setUseScriptEnv();
1771                        consoleVariables.putAndReturnSlef("CommandEnd","/");
1772                        if(enableSystemOut){
1773                            System.out.println("Changed CommandEnd to '/'");
1774                        }
1775                        set("Name",displayEngineName); 
1776                    } else if(executeCommand.toUpperCase().equals("CMD")){
1777                        setUseCmdEnv();
1778                        consoleVariables.putAndReturnSlef("CommandEnd","/");
1779                        if(enableSystemOut){
1780                            System.out.println("Changed CommandEnd to '/'");
1781                        }
1782                        set("Name","cmd"); 
1783                    }else if(executeCommand.toUpperCase().equals("GHOST")){
1784                setUseGhostEnv();
1785                consoleVariables.putAndReturnSlef("CommandEnd","/");
1786                set("Name","ghost");
1787                if(enableSystemOut){
1788                            System.out.println("Changed CommandEnd to '/'");
1789                }
1790                }else if(executeCommand.indexOf(commandHistory) == 0){
1791                            String hiscmd = executeCommand.replaceFirst("^" + commandHistory,"");
1792                        showHistory(hiscmd);
1793                    }else if(executeCommand.toUpperCase().equals("CLEAR")){
1794                        clear(enableSystemOut);
1795                    }else if (executeCommand.toUpperCase().equals("COMMIT")) {
1796                commit(enableSystemOut);
1797                        } else if (executeCommand.toUpperCase().equals("ROLLBACK")) {
1798                                rollback(enableSystemOut);
1799                        } else if (executeCommand.toUpperCase().equals("CLOSE")) {
1800                                close(enableSystemOut);
1801                        } else if (executeCommand.toUpperCase().equals("ABORT")) {
1802                                abort(enableSystemOut);
1803                        }else if (executeCommand.toUpperCase().equals("OPEN")) {
1804                                open(enableSystemOut);
1805                        } else if (executeCommand.matches(CONSOLE_VAR_REGEX)){
1806                            String[] keyValue = executeCommand.split("=",2);
1807                            if(keyValue.length == 2){
1808                                String key = keyValue[0].trim().replaceFirst("^Console\\.","");
1809                                String value = keyValue[1].trim();
1810                                consoleVariables.putAndReturnSlef(key,value);
1811                                if(enableSystemOut) System.out.println(String.format("Successfully Console.%s=%s",key,value));
1812                            }else{
1813                                if(enableSystemOut) System.out.println("ERROR: Invalid console variable");
1814                            }
1815                        } else if (executeCommand.matches(CONSOLE_FUN_REGEX)){
1816                            open(enableSystemOut);
1817                    Pattern pattern = Pattern.compile(CONSOLE_FUN_REGEX);
1818                Matcher matcher = pattern.matcher(executeCommand);
1819                if(matcher.find()){
1820                    String fun = matcher.group(2);
1821                    String paramsStr = matcher.group(3).trim();
1822                    List<String> params = new ArrayList<String>();
1823                    if(!CommonTools.isBlank(paramsStr)){
1824                        params = Arrays.asList(paramsStr.split(","));
1825                    }
1826                    try{
1827                        Method method = JdbcConsole.class.getMethod(fun,List.class);
1828                        Object msg = method.invoke(this,params);
1829                        if(enableSystemOut) {
1830                            if(msg != null){
1831                                System.out.println(msg.toString());
1832                            }
1833                        }
1834                    }catch(Exception e){
1835                        log.error(e.getMessage(),e);
1836                        if(enableSystemOut){ 
1837                            System.out.println(String.format("ERROR: Invalid method '%s'",fun));
1838                            System.out.println(error(e));
1839                        }
1840                    }
1841                }
1842                        } else {
1843                            try{
1844                                Integer queryCursorStart = consoleVariables.getInteger("QueryCursorStart", DEFAULT_QueryCursorStart);
1845                                Integer queryMaxRows = consoleVariables.getInteger("QueryMaxRows",DEFAULT_QueryMaxRows);
1846                                if (executeCommand.toUpperCase().matches(SELECT_REGEX)) {
1847                                    open(enableSystemOut);
1848                                    lastSelectCommand = executeCommand;
1849                                    CacheArray cacheArray = new CacheArray();
1850                                    cacheArray.filter(getCacheArrayFilter(enableSystemOut));
1851                                    cacheDriverExecutor.find(queryCursorStart,queryMaxRows,executeCommand,cacheArray);
1852                                } else if (executeCommand.toUpperCase().matches(CALL_REGEX)) {
1853                                    open(enableSystemOut);
1854                                    lastSelectCommand = executeCommand;
1855                                    String callStoredProcedureFun = consoleVariables.getString("CallStoredProcedureFun",DEFAULT_CallStoredProcedureFun);
1856                                    if(callStoredProcedureFun.equals("callAndReturnList")){
1857                                            CacheArray cacheArray = new CacheArray();
1858                                            cacheArray.filter(getCacheArrayFilter(enableSystemOut));
1859                                            cacheDriverExecutor.callAndReturnList(queryCursorStart,queryMaxRows,executeCommand,cacheArray);  
1860                                    }
1861                                        if(callStoredProcedureFun.equals("callAndReturnRows")){
1862                                                int callRows = cacheDriverExecutor.callAndReturnRows(executeCommand);
1863                                                setIntoValue(callRows);
1864                                                if(enableSystemOut) System.out.println(callRows);
1865                                        }
1866                                        if(callStoredProcedureFun.equals("callAndReturnBoolean")){
1867                                                Boolean callBoolean = cacheDriverExecutor.callAndReturnBoolean(executeCommand);
1868                                                setIntoValue(callBoolean);
1869                                                if(enableSystemOut) System.out.println(callBoolean);
1870                                        }
1871                                }else {
1872                                    open(enableSystemOut);
1873                                    lastSelectCommand = executeCommand;
1874                                    final java.util.Date beginTime = new java.util.Date();
1875                                        int rows = cacheDriverExecutor.execute(executeCommand);
1876                                        long timeCostMs = new java.util.Date().getTime() - beginTime.getTime();
1877                                        setIntoValue(rows);
1878                                        if(enableSystemOut) {
1879                                            System.out.println(String.format("%s row executed (%sms)",rows,timeCostMs));
1880                                        }
1881                                }
1882                            }catch(Exception ee){
1883                                setIntoValue(null);
1884                                throw ee;
1885                            }
1886                        }
1887                } catch (Exception e) {
1888            System.out.println(error(e));
1889            log.info(executeCommand);
1890            log.error(e.getMessage(),e);
1891            if(writeHistory && enableSystemOut && executeCommand.indexOf(commandHistory) != 0){
1892                addHistory(" <INVALID");
1893            }
1894            return false;
1895                } finally{
1896                if(writeHistory && enableSystemOut && executeCommand.indexOf(commandHistory) != 0){
1897                addHistory(System.lineSeparator());
1898                }
1899                }
1900                return true;
1901        }
1902
1903        public CacheArrayFilter getCacheArrayFilter(Boolean enableSystemOut) {
1904                return new CacheArrayFilter(1L,1L) {
1905                        final java.util.Date beginTime = new java.util.Date();
1906                        final List<String> columns = new ArrayList<String>();
1907                        String format = "%" + consoleVariables.getInteger("ColumnWidth", DEFAULT_ColumnWidth) + "s";
1908
1909                        @Override
1910                        public void execute(Integer index, Object o) {
1911                                if (index == 0) {
1912                                        StringBuffer header = new StringBuffer();
1913                                        boolean showResultHeader = consoleVariables.getBoolean("ShowResultHeader",
1914                                                        DEFAULT_ShowResultHeader);
1915                                        Map<String, Object> firstRow = (Map<String, Object>) o;
1916                                        columns.addAll(firstRow.keySet());
1917                                        int columsSize = columns.size();
1918                                        for (int i = 0; i < columsSize; i++) {
1919                                                header.append(String.format(format, columns.get(i)));
1920                                                if (i < columsSize - 1)
1921                                                        header.append("\t");
1922                                        }
1923                                        if(enableSystemOut){
1924                                            try{
1925                                                Thread.sleep(500);
1926                                                System.out.println();
1927                                            }catch(Exception e){
1928                                                log.error(e.getMessage(),e);
1929                                            }
1930                                        }
1931                                        if (enableSystemOut && showResultHeader) {
1932                                                System.out.println(header);
1933                                        }
1934                                }
1935                                if (index >= 0) {
1936                                        int columsSize = columns.size();
1937                                        StringBuffer body = new StringBuffer();
1938                                        boolean showResultBody = consoleVariables.getBoolean("ShowResultBody", DEFAULT_ShowResultBody);
1939                                        Map<String, Object> row = (Map<String, Object>) o;
1940                                        for (int i = 0; i < columsSize; i++) {
1941                                                String column = columns.get(i);
1942                                                Object objValue = row.get(column);
1943                                                String value = format(objValue);
1944                                                if (index == 0 && i == 0) {
1945                                                        setIntoValue(objValue);
1946                                                }
1947                                                body.append(value);
1948                                                if (i < columsSize - 1)
1949                                                        body.append("\t");
1950                                        }
1951                                        if (enableSystemOut && showResultBody) {
1952                                                System.out.println(body);
1953                                        }
1954                                }
1955                        }
1956
1957                        @Override
1958                        public void completed(Integer size) {
1959                                boolean showResultFooter = consoleVariables.getBoolean("ShowResultFooter", DEFAULT_ShowResultFooter);
1960                                if (enableSystemOut && showResultFooter) {
1961                                        long timeCostMs = new java.util.Date().getTime() - beginTime.getTime();
1962                                        String footer = String.format("%s rows selected (%sms)", size, timeCostMs);
1963                                        System.out.println(System.lineSeparator());
1964                                        System.out.println(footer);
1965                                        Integer queryMaxRows = consoleVariables.getInteger("QueryMaxRows",DEFAULT_QueryMaxRows);
1966                                        System.out.println(String.format("Current QueryMaxRows=%s",queryMaxRows));
1967                                }
1968                        }
1969                };
1970        }
1971
1972        public void checkHistory() {
1973                try {
1974                        long pid = ProcessHandle.current().pid();
1975                        String jarPath = getJarPath();
1976                        String historyLog = String.format("%s/history/history_%s.log", getJsPlusPath(), pid);
1977                        File hisFile = new File(historyLog);
1978                        if (hisFile.exists()) {
1979                                SimpleDateFormat sf = new SimpleDateFormat("yyyy.MM.dd_HH:mm:ss.SSS");
1980                                File backupFile = new File(historyLog + ".BAK_" + sf.format(new java.util.Date()));
1981                                hisFile.renameTo(backupFile);
1982                        }
1983                } catch (Exception e) {
1984                        log.error(e.getMessage(), e);
1985                }
1986        }
1987
1988        public void addHistory(String command) {
1989                try {
1990                        long pid = ProcessHandle.current().pid();
1991                        String jarPath = getJarPath();
1992                        String historyLog = String.format("%s/history/history_%s.log", getJsPlusPath(), pid);
1993                        FileTools.write(new File(historyLog), command, true);
1994                } catch (Exception e) {
1995                        log.error(e.getMessage(), e);
1996                }
1997        }
1998
1999        public void showHistory(String hiscmd) {
2000                try {
2001                        long pid = ProcessHandle.current().pid();
2002                        int showLineNum = 0;
2003                        if (!CommonTools.isBlank(hiscmd)) {
2004                                showLineNum = Integer.parseInt(hiscmd.trim());
2005                        }
2006                        String commandHistory = consoleVariables.getString("CommandHistory", DEFAULT_CommandHistory);
2007                        String jarPath = getJarPath();
2008                        String historyLog = String.format("%s/history/history_%s.log", getJsPlusPath(), pid);
2009                        if (!new File(historyLog).exists()) {
2010                                System.out.println("No history log");
2011                                return;
2012                        }
2013                        String hiscmdLines = FileTools.text(historyLog);
2014                        List<String> lines = Arrays.asList(hiscmdLines.split(System.lineSeparator()));
2015                        int size = lines.size();
2016                        for (int i = 0; i < size; i++) {
2017
2018                                if (showLineNum == 0) {
2019                                        String line = lines.get(i);
2020                                        System.out.println(String.format("%s) %s", i + 1, line));
2021                                }
2022                                if (showLineNum > 0 && i == (showLineNum - 1)) {
2023                                        String line = lines.get(showLineNum - 1);
2024                                        System.out.println(String.format("%s) %s", i + 1, line));
2025                                        break;
2026                                }
2027                                if (showLineNum < 0) {
2028                                        int beginIndex = size + showLineNum;
2029                                        beginIndex = beginIndex < 0 ? 0 : beginIndex;
2030                                        if (i >= beginIndex) {
2031                                                String line = lines.get(i);
2032                                                System.out.println(String.format("%s) %s", i + 1, line));
2033                                        }
2034                                }
2035                        }
2036                } catch (Exception e) {
2037                        log.error(e.getMessage(), e);
2038                        System.out.println("ERROR: Invalid history command");
2039                }
2040        }
2041
2042        public String toResultList(List<Map<String, Object>> list) {
2043                String format = "%" + consoleVariables.getInteger("ColumnWidth", DEFAULT_ColumnWidth) + "s";
2044                List<String> columns = null;
2045                StringBuffer body = new StringBuffer();
2046                StringBuffer header = new StringBuffer();
2047                int listSize = list.size();
2048                int columsSize = 0;
2049                if (listSize > 0) {
2050                        Map<String, Object> firstRow = list.get(0);
2051                        columns = new ArrayList<String>(firstRow.keySet());
2052                        columsSize = columns.size();
2053                        for (int i = 0; i < columsSize; i++) {
2054                                header.append(String.format(format, columns.get(i)));
2055                                if (i < columsSize - 1)
2056                                        header.append("\t");
2057                        }
2058                }
2059                for (int i = 0; i < listSize; i++) {
2060                        Map<String, Object> row = list.get(i);
2061                        for (int j = 0; j < columsSize; j++) {
2062                                String column = columns.get(j);
2063                                Object objValue = row.get(column);
2064                                String value = format(objValue);
2065                                body.append(value);
2066                                if (j < columsSize - 1)
2067                                        body.append("\t");
2068                        }
2069                        if (i < listSize - 1)
2070                                body.append(System.lineSeparator());
2071                }
2072                String footer = String.format("%s rows selected", listSize);
2073
2074                boolean showResultHeader = consoleVariables.getBoolean("ShowResultHeader", DEFAULT_ShowResultHeader);
2075                boolean showResultBody = consoleVariables.getBoolean("ShowResultBody", DEFAULT_ShowResultBody);
2076                boolean showResultFooter = consoleVariables.getBoolean("ShowResultFooter", DEFAULT_ShowResultFooter);
2077
2078                StringBuffer result = new StringBuffer();
2079                if (showResultHeader) {
2080                        result.append(header);
2081                        result.append(System.lineSeparator());
2082                }
2083                if (showResultBody) {
2084                        result.append(body);
2085                        result.append(System.lineSeparator());
2086                }
2087                if (showResultFooter) {
2088                        result.append(footer);
2089                }
2090                return result.toString();
2091        }
2092
2093        public boolean isCommandEnd(String command){
2094            String commandEnd = consoleVariables.getString("CommandEnd",DEFAULT_CommandEnd);
2095                return command.matches(".*("+commandEnd+"){1,}[\s]*$");
2096        }
2097
2098        public boolean isCommandCancel(String command){
2099            String commandCancel = consoleVariables.getString("CommandCancel",DEFAULT_CommandCancel);
2100                return command.matches(".*("+commandCancel+"){1,}[\s]*$");
2101        }
2102
2103        public static Map<String, Object> parseArgs(String[] args) {
2104
2105                if (args == null)
2106                        return null;
2107
2108                Map<String, Object> params = null;
2109                List<String> argsArray = Arrays.asList(args);
2110                for (Iterator<String> iterator = argsArray.iterator(); iterator.hasNext();) {
2111
2112                        if (params == null)
2113                                params = new HashMap<String, Object>();
2114
2115                        String arg = iterator.next();
2116                        boolean isKeyValueArg = arg.matches("^-[^-]+$");
2117                        boolean isKeyArg = arg.matches("^--[^-]+$");
2118                        if (isKeyValueArg) {
2119                                String key = arg.replaceFirst("^-", "").trim();
2120                                String value = iterator.next().trim();
2121                                params.put(key, value);
2122                        }
2123                        if (isKeyArg) {
2124                                String key = arg.replaceFirst("^--", "").trim();
2125                                params.put(key, "true");
2126                        }
2127                }
2128                return params;
2129        }
2130        
2131        protected void task() throws Exception {
2132        String task = consoleVariables.getString("Task", DEFAULT_Task);
2133                Long taskTimer = consoleVariables.getMilliSeconds("TaskTimer", DEFAULT_TaskTimer);
2134                task(task,taskTimer);
2135        }       
2136
2137        protected void task(String task,Long taskTimer) throws Exception {
2138                if (!CommonTools.isBlank(task)) {
2139                        long timeout = new java.util.Date().getTime() - preExecuteTime;
2140                        if (timeout >= taskTimer) {
2141                                preExecuteTime = new java.util.Date().getTime();
2142                                String taskFile = null;
2143                                if(Files.exists(Paths.get(task))){
2144                                    taskFile = task;
2145                                }else{
2146                                    taskFile = getJsPlusPath() + "/" + task;
2147                                }
2148                                String commandLines = decryptScript(new File(taskFile));
2149                                String commandEnd = consoleVariables.getString("CommandEnd", DEFAULT_CommandEnd);
2150                                if (!CommonTools.isBlank(commandLines) && !useScriptEnv) {
2151                                        Boolean showTaskLog = consoleVariables.getBoolean("ShowTaskLog", DEFAULT_ShowTaskLog);
2152                                        String[] lines = commandLines.split("\\" + commandEnd + "[^\\S]*[\r]*\n{1,}");
2153                                        int lineSize = lines.length;
2154                                        for (int i = 0; i < lineSize; i++) {
2155                                                String command = lines[i].trim();
2156                                                if (showTaskLog) {
2157                                                        System.out.println(String.format("%s) %s",i, command));
2158                                                }
2159
2160                                                if (command.indexOf("-") == 0)
2161                                                        continue;
2162
2163                                                executeViaJdbc(showTaskLog, command);
2164                                        }
2165                                }
2166                                if(!CommonTools.isBlank(commandLines) && useScriptEnv){
2167                                    executeViaScript(commandLines);
2168                                }
2169                                if(!CommonTools.isBlank(commandLines) && useGhostEnv){
2170                                    executeViaGhost(commandLines);
2171                                }                               
2172                        }
2173                        if (taskTimer <= 0) {
2174                                stopTask();
2175                        }
2176                }
2177        }
2178        
2179        public void setTask(String taskTimer,String task){
2180            set("Task",task);
2181            set("TaskTimer",taskTimer);
2182        }
2183        
2184        public void setTask(String task){
2185            set("Task",task);
2186            set("TaskTimer","0ms");
2187        }       
2188        
2189        public void setTaskTimer(String taskTimer){
2190            set("TaskTimer",taskTimer);
2191        }               
2192
2193        public void taskExecute() {
2194                taskExecuted = true;
2195                ExecutorService executor = Executors.newFixedThreadPool(1);
2196                executor.execute(new Runnable() {
2197
2198                        @Override
2199                        public void run() {
2200
2201                                while (true) {
2202
2203                                        if (Thread.currentThread().isInterrupted())
2204                                                break;
2205
2206                                        try {
2207                                                String task = consoleVariables.getString("Task", DEFAULT_Task);
2208                                                if (!CommonTools.isBlank(task)) {
2209                                                        task();
2210                                                }
2211                                        } catch (Exception e) {
2212                                                log.error(e.getMessage(), e);
2213                                        }
2214                                        try {
2215                                                Thread.sleep(100L);
2216                                        } catch (InterruptedException e) {
2217                                                log.error(e.getMessage(), e);
2218                                        }
2219                                }
2220
2221                        }
2222
2223                });
2224        }
2225
2226        public String importFrom(String schema, String tableName, String csv) throws Exception {
2227                InputStream inputStream = null;
2228                Scanner sc = null;
2229                int updatedRows = 0;
2230                try {
2231                        String tableObjectFolder = String.format("%s/%s_objects", new File(csv).getParent(), tableName);
2232                        Integer batchSize = consoleVariables.getInteger("BatchSize", DEFAULT_BatchSize);
2233                        String importSplit = consoleVariables.getString("ImportSplit", DEFAULT_ImportSplit);
2234                        batchSize = batchSize < 10 ? 10 : batchSize;
2235                        Map<String, Object> classes = cacheDriverExecutor.getColumnClasses(tableName);
2236                        inputStream = new FileInputStream(csv);
2237                        sc = new Scanner(inputStream, BaseFile.CHARSET);
2238                        int r = 0;
2239                        String sql = null;
2240                        final java.util.Date beginTime = new java.util.Date();
2241                        List<Map<String, Object>> records = new ArrayList<Map<String, Object>>();
2242                        List<String> header = new ArrayList<String>();
2243                        while (sc.hasNextLine()) {
2244                                String line = sc.nextLine();
2245                                if (r == 0) {
2246                    if (line.length() > 0 && line.charAt(0) == '\uFEFF') {
2247                        line = line.substring(1);
2248                    }                               
2249                                        String[] hs = line.split(importSplit);
2250                                        for (String h : hs) {
2251                                                if (!CommonTools.isBlank(h)) {
2252                                                        header.add(h.trim());
2253                                                }
2254                                        }
2255                                        sql = converToSqlFromMap(schema, tableName, header);
2256                                }
2257                                if (r > 0) {
2258                                        if (!CommonTools.isBlank(line)) {
2259                                                Map<String, Object> record = new ResultMap<String, Object>();
2260                                                String[] cells = line.split(importSplit);
2261                                                int cellSize = cells.length;
2262                                                for (int c = 0; c < cellSize; c++) {
2263                                                        String cell = cells[c];
2264                                                        String column = header.get(c);
2265                                                        String javaType = (String) classes.get(column);
2266                                                        if (javaType == null) {
2267                                                                javaType = (String) classes.get(column.toLowerCase());
2268                                                        }
2269                                                        if (javaType == null) {
2270                                                                javaType = (String) classes.get(column.toUpperCase());
2271                                                        }
2272                                                        if (javaType == null) {
2273                                                                throw new Exception(
2274                                                                                String.format("Cloumn %s not matched the table %s", column, tableName));
2275                                                        }
2276                                                        record.put(column, conver(tableObjectFolder, javaType, cell));
2277                                                }
2278                                                records.add(record);
2279                                        }
2280                                }
2281                                int mod = r % batchSize;
2282                                if (r > 0 && mod == 0) {
2283                                        updatedRows += cacheDriverExecutor.executeBatch(sql, records);
2284                                        records.clear();
2285                                }
2286                                r++;
2287                        }
2288
2289                        if (records.size() > 0) {
2290                                updatedRows += cacheDriverExecutor.executeBatch(sql, records);
2291                                records.clear();
2292                        }
2293                        long timeCostMs = new java.util.Date().getTime() - beginTime.getTime();
2294                        return String.format("Table %s %s rows inserted (%sms)", tableName, updatedRows, timeCostMs);
2295                } finally {
2296                        if (sc != null)
2297                                sc.close();
2298                        if (inputStream != null)
2299                                inputStream.close();
2300                }
2301        }
2302
2303        public String importTables(String schema, String folder) {
2304                Boolean showTaskLog = consoleVariables.getBoolean("ShowTaskLog", DEFAULT_ShowTaskLog);
2305                int imported = 0;
2306                int failed = 0;
2307                final java.util.Date beginTime = new java.util.Date();
2308                if (showTaskLog) {
2309                        String beginTimeFormat = new SimpleDateFormat(DEFAULT_DateTimeFormat).format(beginTime);
2310                        System.out.println(String.format("Importing tables at %s", beginTimeFormat));
2311                }
2312                StringBuffer importResult = new StringBuffer();
2313                File folderFile = new File(folder);
2314                File[] list = folderFile.listFiles();
2315                Arrays.sort(list);
2316                for (File file : list) {
2317
2318                        if (!file.exists() || !file.isFile())
2319                                continue;
2320
2321                        String fileName = file.getName();
2322                        if (fileName.toUpperCase().endsWith(".CSV")) {
2323                                String tableName = fileName.replaceFirst("\\..*$", "");
2324                                try {
2325                                        if (showTaskLog)
2326                                                System.out.println(String.format("Table %s from %s", tableName, file.getAbsolutePath()));
2327
2328                                        String msg = importFrom(schema, tableName, file.getAbsolutePath());
2329                                        imported++;
2330                                        if (showTaskLog)
2331                                                System.out.println(msg);
2332                                } catch (Exception e) {
2333                                        failed++;
2334                                        log.error(e.getMessage(), e);
2335                                        if (showTaskLog)
2336                                                System.out.println(e.getMessage());
2337                                }
2338                        }
2339                }
2340                java.util.Date completedTime = new java.util.Date();
2341                if (showTaskLog) {
2342                        String completedTimeFormat = new SimpleDateFormat(DEFAULT_DateTimeFormat).format(completedTime);
2343                        System.out.println(String.format("Imported tables at %s", completedTimeFormat));
2344                }
2345                long timeCostMs = completedTime.getTime() - beginTime.getTime();
2346                return String.format("%s tables imported and %s tables failed (%sms)", imported, failed, timeCostMs);
2347        }
2348
2349        public String exportTables(String schema, String exportToFolder) {
2350                Boolean showTaskLog = consoleVariables.getBoolean("ShowTaskLog", DEFAULT_ShowTaskLog);
2351                int exported = 0;
2352                int failed = 0;
2353                final java.util.Date beginTime = new java.util.Date();
2354                if (showTaskLog) {
2355                        String beginTimeFormat = new SimpleDateFormat(DEFAULT_DateTimeFormat).format(beginTime);
2356                        System.out.println(String.format("Exporting tables at %s", beginTimeFormat));
2357                }
2358                try {
2359                        final List<String> tables = new ArrayList<String>();
2360                        if (CommonTools.isBlank(schema)) {
2361                                List<Map<String, Object>> list = cacheDriverExecutor.getAllTables();
2362                                for (Map<String, Object> map : list) {
2363                                        String tableSchema = (String) map.get("TABLE_SCHEMA");
2364                                        String tableName = (String) map.get("TABLE_NAME");
2365                                        String schemaTableName = tableName;
2366                                        if (!CommonTools.isBlank(tableSchema)) {
2367                                                schemaTableName = String.format("%s.%s", tableSchema, tableName);
2368                                        }
2369                                        if (!tables.contains(schemaTableName))
2370                                                tables.add(schemaTableName);
2371                                }
2372                        } else {
2373                                List<Map<String, Object>> list = cacheDriverExecutor.getAllTables();
2374                                for (Map<String, Object> map : list) {
2375                                        String tableSchema = (String) map.get("TABLE_SCHEMA");
2376                                        String tableName = (String) map.get("TABLE_NAME");
2377                                        if (!CommonTools.isBlank(tableSchema)) {
2378                                                if (schema.equalsIgnoreCase(tableSchema)) {
2379                                                        String schemaTableName = String.format("%s.%s", tableSchema, tableName);
2380
2381                                                        if (!tables.contains(schemaTableName))
2382                                                                tables.add(schemaTableName);
2383                                                }
2384                                        }
2385                                }
2386                        }
2387                        String exportOrderBy = consoleVariables.getString("ExportOrderBy", DEFAULT_ExportOrderBy);
2388                        for (String table : tables) {
2389                                String command = String.format("SELECT * FROM %s %s", quote(table), exportOrderBy);
2390                                String fileName = String.format("%s/%s", exportToFolder,
2391                                                exportUpperOrLowerCase(table.replaceFirst("\\.", "/")));
2392                                File file = new File(fileName);
2393                                boolean success = false;
2394                                try {
2395                                    exportTo(command,file.getAbsolutePath());
2396                                        exported++;
2397                                } catch (Exception ee) {
2398                                        log.error(ee);
2399                                        failed++;
2400                                }
2401                        }
2402                        java.util.Date completedTime = new java.util.Date();
2403                        if (showTaskLog) {
2404                                String completedTimeFormat = new SimpleDateFormat(DEFAULT_DateTimeFormat).format(completedTime);
2405                                System.out.println(String.format("Exported tables at %s", completedTimeFormat));
2406                        }
2407                        long timeCostMs = completedTime.getTime() - beginTime.getTime();
2408                        return String.format("*********%s tables exported and %s tables failed (%sms)*********", exported, failed,
2409                                        timeCostMs);
2410                } catch (Exception e) {
2411                        log.error(e.getMessage(), e);
2412                        return e.getMessage();
2413                }
2414        }
2415
2416        public String quote(String tableOrColumn) {
2417                String quote = consoleVariables.getString("Quote", DEFAULT_Quote);
2418                String[] schemaTableOrColumn = tableOrColumn.split("\\.");
2419                if (schemaTableOrColumn.length == 1) {
2420                        return String.format(quote, tableOrColumn);
2421                }
2422                if (schemaTableOrColumn.length == 2) {
2423                        String quoteSchema = String.format(quote, schemaTableOrColumn[0]);
2424                        String quoteTable = String.format(quote, schemaTableOrColumn[1]);
2425                        return String.format("%s.%s", quoteSchema, quoteTable);
2426                }
2427                return tableOrColumn;
2428        }
2429
2430        public void setIntoValue(Object value) {
2431                if (CommonTools.isBlank(value)) {
2432                        intoValue = "NULL";
2433                } else {
2434                        if (value instanceof List) {
2435                                List<Map<String, Object>> list = (List<Map<String, Object>>) value;
2436                                if (list.size() > 0) {
2437                                        Map<String, Object> map = list.get(0);
2438                                        List<String> keys = new ArrayList<String>(map.keySet());
2439                                        String key = keys.get(0);
2440                                        intoValue = formatForExport(map.get(key));
2441                                }
2442                        } else {
2443                                intoValue = formatForExport(value);
2444                        }
2445                }
2446        }
2447
2448        public String formatCommand(String command) {
2449
2450                if (command == null)
2451                        return null;
2452
2453                Pattern pattern = Pattern.compile("\\{([a-zA-Z0-9_]+)\\}");
2454                Matcher matcher = pattern.matcher(command);
2455                List<String> intoNames = new ArrayList<String>();
2456                while (matcher.find()) {
2457                        intoNames.add(matcher.group(1));
2458                }
2459                for (String intoName : intoNames) {
2460                        command = command.replaceAll(String.format("\\{%s\\}", intoName), consoleVariables.getString(intoName));
2461                }
2462                return command;
2463        }
2464
2465        public String exportUpperOrLowerCase(String s) {
2466                String exportUpperOrLowerCase = consoleVariables.getString("ExportUpperOrLowerCase",
2467                                DEFAULT_ExportUpperOrLowerCase);
2468                if (exportUpperOrLowerCase.equalsIgnoreCase("Upper")) {
2469                        return s.toUpperCase();
2470                }
2471                if (exportUpperOrLowerCase.equalsIgnoreCase("Lower")) {
2472                        return s.toLowerCase();
2473                }
2474                return s;
2475        }
2476        
2477        public CmdConsole getCmdConsole(){
2478            return cmdConsole;
2479        }
2480
2481        public static String error(Exception e) {
2482                if (e instanceof SQLException) {
2483                        SQLException se = (SQLException) e;
2484                        return String.format("ERROR: (%s) %s", se.getErrorCode(), se.getMessage());
2485                } else {
2486                        return String.format("ERROR: %s", e.getMessage());
2487                }
2488        }
2489    
2490        public synchronized static String exit() {
2491            try{
2492                String exitTmpPathStr = String.format("%s/exit.tmp", tmpPath.toString());
2493                Path exitTmpPath = Paths.get(exitTmpPathStr);
2494                DiskFile exitTmpDf = new DiskFile(exitTmpPathStr);
2495                exitTmpDf.write(System.currentTimeMillis() + "");
2496                return "Successfully";
2497            }catch(Exception e){
2498                        LoggerFactory.getLogger(ScriptConsole.class).error(e.getMessage(), e);
2499                        return String.format("ERROR: %s", e.getMessage());
2500            }
2501        }
2502        
2503    public long memoryUsing(){
2504        int mb = 1024 * 1024;
2505                Runtime instance = Runtime.getRuntime();
2506                long totalMemory = instance.totalMemory() / mb;
2507                long freeMemory = instance.freeMemory() / mb;
2508                return  (instance.totalMemory() - instance.freeMemory()) / mb;
2509    }   
2510
2511    public double memoryUsage(long using){
2512        int mb = 1024 * 1024;
2513                Runtime instance = Runtime.getRuntime();
2514                long maxMemory = instance.maxMemory() / mb;
2515                return (using * 1.0D / maxMemory * 1.0D);
2516    }   
2517    
2518    public double memoryUsage(){
2519        return memoryUsage(memoryUsing());
2520    }           
2521
2522        public void addExitRunnable(Runnable exitRun) {
2523                exitRuns.add(exitRun);
2524        }
2525
2526        public String version() {
2527                return VERSION;
2528        }
2529        
2530        public void setUseGhostEnv(){
2531            this.useScriptEnv = false;
2532        this.useJdbcEnv = false;
2533        this.useCmdEnv = false; 
2534        this.useGhostEnv = true; 
2535        set("Name","ghost");
2536        }       
2537        
2538        public void setUseJdbcEnv(){
2539            this.useScriptEnv = false;
2540        this.useJdbcEnv = true;
2541        this.useCmdEnv = false; 
2542        this.useGhostEnv = false; 
2543        set("Name","jdbc");
2544        }
2545        
2546        public void setUseScriptEnv(){
2547            this.useScriptEnv = true;
2548        this.useJdbcEnv = false;
2549        this.useCmdEnv = false;
2550        this.useGhostEnv = false; 
2551        }       
2552        
2553        public void setUseCmdEnv(){
2554            this.useScriptEnv = false;
2555        this.useJdbcEnv = false;
2556        this.useCmdEnv = true;
2557        this.useGhostEnv = false; 
2558        set("Name","cmd");
2559        }
2560        
2561        public boolean isUseGhostEnv(){
2562        return this.useGhostEnv;
2563        }       
2564        
2565        public boolean isUseJdbcEnv(){
2566        return this.useJdbcEnv;
2567        }       
2568        
2569        public boolean isUseScriptEnv(){
2570            return this.useScriptEnv;
2571        }               
2572        
2573        public boolean isUseCmdEnv(){
2574        return this.useCmdEnv;
2575        }       
2576
2577        public String help() {
2578                StringBuffer content = new StringBuffer();
2579                content.append("---------------------------------------------------------");
2580                content.append(System.lineSeparator());
2581                content.append("Usage,");
2582                content.append(System.lineSeparator());
2583                content.append("> java -jar jsplus-embed.jar [Options]");
2584                content.append(System.lineSeparator());
2585                content.append(System.lineSeparator());
2586                content.append("DataSource Options,");
2587                content.append(System.lineSeparator());
2588                content.append("*The following parameters will override the 'DataSource.properties' settings*");
2589                content.append(System.lineSeparator());
2590                content.append("-ThreadName               - ThreadName, default is 'DriverDataSource',eg. Console_DS");
2591                content.append(System.lineSeparator());
2592                content.append("-DriverJar                - DriverJar, eg. /jdbc/db_driver.jar");
2593                content.append(System.lineSeparator());
2594                content.append("-Driver                   - Driver, JDBC driver class name");
2595                content.append(System.lineSeparator());
2596                content.append("-Url                      - Url, Connection string");
2597                content.append(System.lineSeparator());
2598                content.append("-Username                 - Username, Database account");
2599                content.append(System.lineSeparator());
2600                content.append("-Password                 - Password, Database password");
2601                content.append(System.lineSeparator());
2602                content.append("-TestValidTimeout         - TestValidTimeout, default is 5s");
2603                content.append(System.lineSeparator());
2604                content.append("-RefreshPoolTimer         - RefreshPoolTimer, default is 1s");
2605                content.append(System.lineSeparator());
2606                content.append("-IdleTimeout              - IdleTimeout, default is 60s");
2607                content.append(System.lineSeparator());
2608                content.append("-Timeout                  - Query or execute timeout, 0s is disabled, default is 0s");
2609                content.append(System.lineSeparator());
2610                content.append(
2611                                "-TransactionTimeout       - Query or execute timeout if auto commit is false, 0s is disabled, default is 0s");
2612                content.append(System.lineSeparator());
2613                content.append("-LifeCycle                - LifeCycle, default is Long.MAX_VALUE");
2614                content.append(System.lineSeparator());
2615                content.append("-MinPoolSize              - MinPoolSize, default is 0");
2616                content.append(System.lineSeparator());
2617                content.append("-MaxPoolSize              - MaxPoolSize, default is Integer.MAX_VALUE");
2618                content.append(System.lineSeparator());
2619                content.append("-ConnProps                - ConnProps, Defaul is empty");
2620                content.append(System.lineSeparator());
2621                content.append("-EnableStatusLog          - EnableStatusLog, default is false");
2622                content.append(System.lineSeparator());
2623                content.append(
2624                                "-StatusLogFolder          - StatusLogFolder, Write to jar location if value is empty, default is empty");
2625
2626                content.append(System.lineSeparator());
2627                content.append(
2628                                "-AllowAllAccess          - AllowAllAccess, Default is true");
2629
2630                content.append(System.lineSeparator());         
2631                content.append(System.lineSeparator());
2632                content.append("Task Options,");
2633                content.append(System.lineSeparator());
2634                content.append("-TaskTimer                - Task timer, 0s is run once only, Default 0s");
2635                content.append(System.lineSeparator());
2636                content.append("-Task                     - Task batch file path, Default is empty");
2637                content.append(System.lineSeparator());
2638                content.append("-Env                      - 'cmd/jdbc/script', Default is 'jdbc'");
2639                content.append(System.lineSeparator());
2640                content.append("-ScriptEngine             - Default is 'nashorn'");
2641                content.append(System.lineSeparator());
2642                content.append(System.lineSeparator());
2643                content.append("Others,");
2644                content.append(System.lineSeparator());
2645                content.append("--exit                    - Exit all.");                
2646                content.append(System.lineSeparator());
2647                content.append("--help                    - Display help info.");
2648                content.append(System.lineSeparator());
2649                content.append("--version                 - Display version.");
2650
2651                return content.toString();
2652        }
2653        
2654        public void connect(int consoleHashCode) {
2655        ScriptConsole sc = CONNECT_CONSOLES.get(consoleHashCode);
2656        if(sc == null){
2657            System.out.println("Missing Console: " + consoleHashCode);
2658        }
2659        if(sc != null){
2660            ScriptConsole currentConsole = CONNECT_CONSOLES.get(0);
2661            CONNECT_CONSOLES.put(0,sc);
2662            if(currentConsole != null){
2663                System.out.println("Origin Console: " + currentConsole.hashCode());
2664            }
2665            System.out.println("Connected Console: " + consoleHashCode);
2666            set("Name",sc.displayEngineName);
2667        }
2668        }
2669        
2670        protected ScriptConsole getConsole(){
2671
2672        ScriptConsole sc = CONNECT_CONSOLES.get(0);
2673        
2674        if(sc != null) return sc;
2675
2676            return this;
2677        }
2678        
2679        protected String getDisplayEngineName(){
2680            if(isUseJdbcEnv()) return "jdbc";
2681            
2682            if(isUseCmdEnv()) return "cmd";
2683            
2684            if(isUseGhostEnv()) return "ghost";
2685            
2686            if(isUseScriptEnv()) return displayEngineName;
2687            
2688            return "";
2689        }
2690        
2691        public Map<Integer,ScriptConsole> getConsoles(){
2692            return CONNECT_CONSOLES;
2693        }
2694        
2695        public String decryptScript(File scriptPath) throws Exception {
2696            String aesKey = consoleVariables.getString("Script_Cipher_AesKey", DEFAULT_Script_Cipher_AesKey);
2697            String script = null;
2698            if(CommonTools.isBlank(aesKey)){
2699                script = FileTools.text(scriptPath);
2700            }else{
2701                DiskFile df = new DiskFile(scriptPath);
2702                byte[] encryptBytes = df.readAllBytes();
2703                byte[] decryptBytes = CipherTools.AESDecrypt(aesKey,encryptBytes);
2704                script = new String(decryptBytes,BaseFile.CHARSET);
2705            }
2706            return script;
2707        }
2708
2709    public synchronized void startSchedule() {
2710        if (scheduleExecutor == null) {
2711            scheduleExecutor = Executors.newSingleThreadScheduledExecutor();
2712            scheduleNextMinute();
2713        }
2714    }
2715    
2716    private void scheduleNextMinute() {
2717        long delay = getDelayToNextMinute();
2718        scheduleExecutor.schedule(new Runnable() {
2719            @Override
2720            public void run() {
2721                try {
2722                    executeTasks();
2723                } finally {
2724                    scheduleNextMinute();
2725                }
2726            }
2727        }, delay, TimeUnit.MILLISECONDS);
2728    }
2729    
2730    private void executeTasks() {
2731        try{
2732            List<String> nameList = new ArrayList<String>(scheduleMap.keySet());
2733            for (String name : nameList) {
2734                Thread.currentThread().setName("executeTasks-" + name);
2735                Map<String, Object> taskMap = scheduleMap.get(name);
2736                String cronRules = (String) taskMap.get("cronRules");
2737                Runnable runnable = (Runnable) taskMap.get("runnable");
2738                Clock clock = new Clock();
2739                Date date = clock.getDate();
2740                String currentMinsStr = new SimpleDateFormat("mm").format(date).toUpperCase();
2741                String currentTimeStr = new SimpleDateFormat("HH:mm").format(date).toUpperCase();
2742                String currentDayTimeStr = new SimpleDateFormat("E HH:mm").format(date).toUpperCase();
2743                List<String> cronRulesList = Arrays.asList(cronRules.trim().toUpperCase().split(",|;"));
2744                int currentMins = Integer.parseInt(currentMinsStr);
2745                boolean haveStar = cronRules.indexOf("*") >= 0;
2746                boolean matchedStar = false;
2747                if(haveStar && cronRulesList.size() == 1){
2748                    String minStr = cronRules.replaceFirst("^\\*","");
2749                    if(CommonTools.isBlank(minStr)){
2750                        minStr = "1";
2751                    }
2752                    int min = Integer.parseInt(minStr);
2753                    matchedStar = (currentMins <= 0 || currentMins % min <= 0);
2754                }   
2755                boolean matched = cronRulesList.contains(currentTimeStr) 
2756                               || cronRulesList.contains(currentDayTimeStr)
2757                               || cronRulesList.contains(currentMinsStr)
2758                               || matchedStar;
2759                if (matched) {
2760                    try {
2761                        if (runnable != null) {
2762                            Executors.newSingleThreadExecutor().execute(runnable);
2763                        }
2764                    } catch (Exception e) {
2765                        log.error(e.getMessage(), e);
2766                    }
2767                }
2768            }            
2769        }catch(Exception e){
2770            log.error(e.getMessage(), e);
2771        }
2772    }
2773        
2774        public void addSchedule(String name,String cronRules,Runnable runnable) {
2775            clearSchedule(name);
2776            final Map<String,Object> map = new HashMap<String,Object>();
2777            map.put("cronRules",cronRules);
2778            map.put("runnable",runnable);
2779            scheduleMap.put(name,map);
2780        }
2781        
2782        public void clearSchedule(String name) {
2783            scheduleMap.remove(name);
2784        }
2785        
2786        public void clearAllSchedule(String name) {
2787            scheduleMap.clear();
2788        }       
2789        
2790        public Map<String,Map<String,Object>> getScheduleMap() {
2791            return new HashMap<String, Map<String,Object>>(scheduleMap);
2792        }
2793        
2794    private long getDelayToNextMinute() {
2795        long now = System.currentTimeMillis();
2796        long nextMinute = ((now / 60000) + 1) * 60000;
2797        long delay = nextMinute - now;
2798        return delay > 0 ? delay : 60000;
2799    }   
2800        
2801        /* For base console */
2802        
2803        
2804        public Object version(List<String> params) {
2805                if (params.size() > 0) {
2806                        return "ERROR: Invalid params, eg.'Console.version()'";
2807                }
2808                try {
2809                        return version();
2810                } catch (Exception e) {
2811                        log.error(e.getMessage(), e);
2812                        return ScriptConsole.error(e);
2813                }
2814        }
2815
2816        public Object help(List<String> params) {
2817                if (params.size() > 0) {
2818                        return "ERROR: Invalid params, eg.'Console.help()'";
2819                }
2820                try {
2821                        return help();
2822                } catch (Exception e) {
2823                        log.error(e.getMessage(), e);
2824                        return ScriptConsole.error(e);
2825                }
2826        }
2827
2828        public Object exit(List<String> params) {
2829                if (params.size() > 0) {
2830                        return "ERROR: Invalid params, eg.'Console.exit()'";
2831                }
2832                try {
2833                        return ScriptConsole.exit();
2834                } catch (Exception e) {
2835                        log.error(e.getMessage(), e);
2836                        return ScriptConsole.error(e);
2837                }
2838        }
2839
2840        public Object reset(List<String> params) {
2841                if (params.size() > 0) {
2842                        return "ERROR: Invalid params, eg.'Console.reset()'";
2843                }
2844                reset();
2845                return "Successfully";
2846        }
2847
2848        public Object setCacheApi(List<String> params) {
2849            if(isUseScriptEnv()){
2850                return "ERROR: JDBC or CMD environment is supported.";
2851            }       
2852                if (params.size() > 1) {
2853                        return "ERROR: Invalid params, eg.'Console.setCacheApi(apiClass)'";
2854                }
2855                try {
2856                        String apiClass = formatCommand(params.get(0).trim());
2857                        setCacheApi(apiClass);
2858                        return String.format("Changed cache api to %s", apiClass);
2859                } catch (Exception e) {
2860                        log.error(e.getMessage(), e);
2861                        return ScriptConsole.error(e);
2862                }
2863        }
2864
2865        public Object when(List<String> params) {
2866            if(isUseScriptEnv()){
2867                return "ERROR: JDBC or CMD environment is supported.";
2868            }       
2869                if (params.size() == 0 || params.size() > 3) {
2870                        return "ERROR: Invalid params, eg.'Console.when(variableName,compareValue,batchFile)'";
2871                }
2872                try {
2873                        String variableName = formatCommand(params.get(0).trim());
2874                        String compareValue = formatCommand(params.get(1).trim());
2875                        String batchFile = formatCommand(params.get(2).trim());
2876                        String variableValue = consoleVariables.getString(variableName);
2877                        if (CommonTools.isBlank(variableValue)) {
2878                                variableValue = "NULL";
2879                        }
2880                        if (variableValue.equals(compareValue)) {
2881                                Object msg = executeBatch(batchFile);
2882                                return msg;
2883                        } else {
2884                                return String.format("No matched compare (%s != %s)", variableValue, compareValue);
2885                        }
2886                } catch (Exception e) {
2887                        log.error(e.getMessage(), e);
2888                        return ScriptConsole.error(e);
2889                }
2890        }
2891
2892        public Object into(List<String> params) {
2893            if(isUseScriptEnv()){
2894                return "ERROR: JDBC or CMD environment is supported.";
2895            }       
2896                if (params.size() > 1) {
2897                        return "ERROR: Invalid params, eg.'Console.into(variableName)'";
2898                }
2899                String name = formatCommand(params.get(0).trim());
2900                into(name);
2901                return null;
2902        }
2903
2904        public Object batch(List<String> params) {
2905            if(isUseScriptEnv()){
2906                return "ERROR: JDBC or CMD environment is supported.";
2907            }       
2908                if (params.size() == 0 || params.size() > 1) {
2909                        return "ERROR: Invalid params, eg.'Console.batch(path)'";
2910                }
2911                if (params.size() == 1) {
2912                    try{
2913                        String batFile = formatCommand(params.get(0));
2914                        if (CommonTools.isBlank(batFile)) {
2915                                return "ERROR: Invalid params, eg.'Console.batch(path)'";
2916                        }
2917                        Object msg = executeBatch(batFile);
2918                        return msg;
2919                    }catch(Exception e){
2920                        log.error(e.getMessage(), e);
2921                        return ScriptConsole.error(e);
2922                    }
2923                }
2924                return "Successfully";
2925        }
2926
2927        public Object sleep(List<String> params) {
2928            if(isUseScriptEnv()){
2929                return "ERROR: JDBC or CMD environment is supported.";
2930            }       
2931                if (params.size() == 0 || params.size() > 1) {
2932                        return "ERROR: Invalid params, eg.'Console.sleep(10s)'";
2933                }
2934                String ms = "0s";
2935                if (params.size() == 1) {
2936                        ms = formatCommand(params.get(0).trim());
2937                }
2938                try {
2939                        sleep(ms);
2940                        return "Successfully";
2941                } catch (Exception e) {
2942                        log.error(e.getMessage(), e);
2943                        return ScriptConsole.error(e);
2944                }
2945        }
2946
2947        public Object hostname(List<String> params) {
2948            if(isUseScriptEnv()){
2949                return "ERROR: JDBC or CMD environment is supported.";
2950            }       
2951                if (params.size() > 0) {
2952                        return "ERROR: Invalid params, eg.'Console.hostname()'";
2953                }
2954                try {
2955                        return hostname();
2956                } catch (Exception e) {
2957                        log.error(e.getMessage(), e);
2958                        return ScriptConsole.error(e);
2959                }
2960        }
2961
2962        public Object startTask(List<String> params) {
2963            if(isUseScriptEnv()){
2964                return "ERROR: JDBC or CMD environment is supported.";
2965            }       
2966                if (params.size() == 0 || params.size() > 2) {
2967                        return "ERROR: Invalid params, eg.'Console.startTask(10s,path) or startTask(path)'";
2968                }
2969                String taskTimer = null;
2970                String task = null;
2971                if (params.size() == 1) {
2972                        task = formatCommand(params.get(0).trim());
2973                }
2974                if (params.size() == 2) {
2975                        taskTimer = formatCommand(params.get(0).trim());
2976                        task = formatCommand(params.get(1).trim());
2977                }
2978                startTask(taskTimer, task);
2979                return "Successfully";
2980        }
2981
2982        public Object stopTask(List<String> params) {
2983            if(isUseScriptEnv()){
2984                return "ERROR: JDBC or CMD environment is supported.";
2985            }       
2986                if (params.size() == 0) {
2987                        stopTask();
2988                        return "Successfully";
2989                } else {
2990                        return "ERROR: Invalid params, eg.'Console.stopTask()'";
2991                }
2992        }
2993
2994        public Object set(List<String> params) {
2995            if(isUseScriptEnv()){
2996                return "ERROR: JDBC or CMD environment is supported.";
2997            }       
2998                if (params.size() == 0 || params.size() > 2) {
2999                        return "ERROR: Invalid params, eg.'Console.set(variableName,value)'";
3000                }
3001                if (params.size() == 2) {
3002                        String key = formatCommand(params.get(0).trim());
3003                        String value = formatCommand(params.get(1));
3004                        return set(key, value);
3005                }
3006                return null;
3007        }
3008
3009        public Object show(List<String> params) {
3010            if(isUseScriptEnv()){
3011                return "ERROR: JDBC or CMD environment is supported.";
3012            }       
3013                if (params.size() == 0 || params.size() > 1) {
3014                        return "ERROR: Invalid params, eg.'Console.show(variableName)'";
3015                }
3016                if (params.size() == 1) {
3017                        String key = formatCommand(params.get(0).trim());
3018                        return show(key);
3019                }
3020                return null;
3021        }
3022
3023        public Object showAll(List<String> params) {
3024                if (params.size() > 0) {
3025                        return "ERROR: Invalid params, eg.'Console.showAll()'";
3026                }
3027                return showAll();
3028        }
3029        
3030        /*For jdbc console*/
3031        
3032        public Object importTables(List<String> params) {
3033            if(!isUseJdbcEnv()){
3034                return "ERROR: JDBC environment is supported only.";
3035            }       
3036                if (params.size() == 0 && params.size() > 2) {
3037                        return "ERROR: Invalid params, eg.'Console.importTables(csvFolder) or Console.importTables(schema,csvFolder)'";
3038                }
3039                String schema = null;
3040                String csvFolder = null;
3041                if (params.size() == 1) {
3042                        schema = null;
3043                        csvFolder = formatCommand(params.get(0).trim());
3044                }
3045                if (params.size() == 2) {
3046                        schema = formatCommand(params.get(0).trim());
3047                        csvFolder = formatCommand(params.get(1).trim());
3048                }
3049                return importTables(schema, csvFolder);
3050        }
3051
3052        public Object clearLastSelectCommand(List<String> params) {
3053            if(!isUseJdbcEnv()){
3054                return "ERROR: JDBC environment is supported only.";
3055            }       
3056                if (params.size() > 0) {
3057                        return "ERROR: Invalid params, eg.'Console.clearLastSelectCommand()'";
3058                }
3059                clearLastSelectCommand();
3060                return "Cleared last select command";
3061        }
3062
3063        public Object exportTables(List<String> params) {
3064            if(!isUseJdbcEnv()){
3065                return "ERROR: JDBC environment is supported only.";
3066            }       
3067                if (params.size() == 0 || params.size() > 2) {
3068                        return "ERROR: Invalid params, eg.'Console.exportTables(schema,toCsvFolder) or Console.exportTables(toCsvFolder)'";
3069                }
3070
3071                String _aesKey = consoleVariables.getString("JdbcCipherAesKey");
3072                boolean useEncrypt = !CommonTools.isBlank(_aesKey);
3073                if (useEncrypt) {
3074                        if (_aesKey.length() < 16 || _aesKey.length() > 256) {
3075                                return "ERROR: Invalid Console.JdbcCipherAesKey (Required 16 - 256 chars)";
3076                        }
3077                        System.out.println("*********************************************");
3078                        System.out.println("Please remember the info(For import),");
3079                        System.out.println(String.format("Console.JdbcCipherAesKey=%s;", _aesKey));
3080                        System.out.println("*********************************************");
3081                }
3082
3083                try {
3084                        String schema = null;
3085                        String exportToFolder = null;
3086                        if (params.size() == 1) {
3087                                schema = null;
3088                                exportToFolder = formatCommand(params.get(0).trim());
3089                        }
3090                        if (params.size() == 2) {
3091                                schema = formatCommand(params.get(0).trim()).toUpperCase().equals("NULL") ? null : params.get(0).trim();
3092                                exportToFolder = formatCommand(params.get(1).trim());
3093                        }
3094                        return exportTables(schema, exportToFolder);
3095                } catch (Exception e) {
3096                        log.error(e.getMessage(), e);
3097                        return ScriptConsole.error(e);
3098                }
3099        }
3100
3101        public Object desc(List<String> params) {
3102            if(!isUseJdbcEnv()){
3103                return "ERROR: JDBC environment is supported only.";
3104            }       
3105                if (params.size() == 0 || params.size() > 2) {
3106                        return "ERROR: Invalid params, eg.'Console.desc(tableName) or Console.desc(schema,tableName)'";
3107                }
3108                try {
3109                        String schema = null;
3110                        String tableName = null;
3111                        if (params.size() == 1) {
3112                                tableName = formatCommand(params.get(0).trim());
3113                        }
3114                        if (params.size() == 2) {
3115                                schema = formatCommand(params.get(0).trim());
3116                                tableName = formatCommand(params.get(1).trim());
3117                        }
3118                        List<Map<String, Object>> list = desc(schema, tableName);
3119                        String lines = toResultList(list);
3120                        return lines;
3121                } catch (Exception e) {
3122                        log.error(e.getMessage(), e);
3123                        return ScriptConsole.error(e);
3124                }
3125        }
3126
3127        public Object showTables(List<String> params) {
3128            if(!isUseJdbcEnv()){
3129                return "ERROR: JDBC environment is supported only.";
3130            }       
3131                if (params.size() > 1) {
3132                        return "ERROR: Invalid params, eg.'Console.showTables() or Console.showTables(schema)'";
3133                }
3134                try {
3135                        String schema = null;
3136                        List<Map<String, Object>> tables = new ArrayList<Map<String, Object>>();
3137                        if (params.size() == 1) {
3138                                schema = formatCommand(params.get(0).trim());
3139                        }
3140                        tables.addAll(showTables(schema));
3141                        String lines = toResultList(tables);
3142                        return lines;
3143                } catch (Exception e) {
3144                        log.error(e.getMessage(), e);
3145                        return ScriptConsole.error(e);
3146                }
3147        }
3148
3149        public Object showColumnTypes(List<String> params) {
3150            if(!isUseJdbcEnv()){
3151                return "ERROR: JDBC environment is supported only.";
3152            }       
3153                if (params.size() == 0 || params.size() > 1) {
3154                        return "ERROR: Invalid params, eg.'Console.showColumnTypes(tableName)'";
3155                }
3156                try {
3157                        String tableName = formatCommand(params.get(0).trim());
3158                        Map<String, Object> result = showColumnTypes(tableName);
3159                        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
3160                        list.add(result);
3161                        String lines = toResultList(list);
3162                        return lines;
3163                } catch (Exception e) {
3164                        log.error(e.getMessage(), e);
3165                        return ScriptConsole.error(e);
3166                }
3167        }
3168
3169        public Object showColumnClasses(List<String> params) {
3170            if(!isUseJdbcEnv()){
3171                return "ERROR: JDBC environment is supported only.";
3172            }       
3173                if (params.size() == 0 || params.size() > 1) {
3174                        return "ERROR: Invalid params, eg.'Console.showColumnClasses(tableName)'";
3175                }
3176                try {
3177                        String tableName = formatCommand(params.get(0).trim());
3178                        Map<String, Object> result = (Map<String, Object>) showColumnClasses(tableName);
3179                        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
3180                        list.add(result);
3181                        String lines = toResultList(list);
3182                        return lines;
3183                } catch (Exception e) {
3184                        log.error(e.getMessage(), e);
3185                        return ScriptConsole.error(e);
3186                }
3187        }
3188
3189        public Object exportTo(List<String> params) {
3190            if(!isUseJdbcEnv()){
3191                return "ERROR: JDBC environment is supported only.";
3192            }       
3193                if (params.size() == 0 || params.size() > 2) {
3194                        return "ERROR: Invalid params, eg.'Console.exportTo(path)'";
3195                }
3196                try {
3197                    if(params.size() == 1){
3198                        String file = formatCommand(params.get(0).trim());
3199                        if (CommonTools.isBlank(file)) {
3200                                return "ERROR: Invalid params, eg.'Console.exportTo(path)'";
3201                        }
3202                        exportTo(file);
3203                    }
3204                    if(params.size() == 2){
3205                        String folder = formatCommand(params.get(0).trim());
3206                        String filePrefix = formatCommand(params.get(1).trim());
3207                        if (CommonTools.isBlank(folder) || CommonTools.isBlank(filePrefix)) {
3208                                return "ERROR: Invalid params, eg.'Console.exportTo(folder,filePrefix)'";
3209                        }
3210                        exportTo(new File(folder),filePrefix);
3211                    }               
3212                        return "Successfully";
3213                } catch (Exception e) {
3214                        return ScriptConsole.error(e);
3215                }
3216        }
3217
3218        public Object importFrom(List<String> params) {
3219            if(!isUseJdbcEnv()){
3220                return "ERROR: JDBC environment is supported only.";
3221            }
3222                if (params.size() == 0 || params.size() == 1 || params.size() > 3) {
3223                        return "ERROR: Invalid params, eg.'Console.importFrom(schema,tableName,csv) or Console.importFrom(tableName,csv)'";
3224                }
3225                try {
3226                        String schema = null;
3227                        String tableName = null;
3228                        Integer batchSize = consoleVariables.getInteger("BatchSize", DEFAULT_BatchSize);
3229                        String csv = null;
3230                        if (params.size() == 2) {
3231                                tableName = formatCommand(params.get(0).trim());
3232                                csv = params.get(1).trim();
3233                        }
3234                        if (params.size() == 3) {
3235                                schema = formatCommand(params.get(0).trim()).toUpperCase().equals("NULL") ? null : params.get(0).trim();
3236                                tableName = formatCommand(params.get(1).trim());
3237                                csv = params.get(2).trim();
3238                        }
3239                        return importFrom(schema, tableName, csv);
3240                } catch (Exception e) {
3241                        log.error(e.getMessage(), e);
3242                        return ScriptConsole.error(e);
3243                }
3244        }       
3245        
3246        public Object setAutoCommit(List<String> params) {
3247            if(!isUseJdbcEnv()){
3248                return "ERROR: JDBC environment is supported only.";
3249            }       
3250                if (params.size() == 0 || params.size() > 1) {
3251                        return "ERROR: Invalid params, eg.'Console.setAutoCommit(true/false)'";
3252                }
3253                Boolean autoCommit = null;
3254                try {
3255                        if (params.size() == 1) {
3256                                autoCommit = Boolean.parseBoolean(formatCommand(params.get(0).trim()));
3257                        }
3258                        Boolean b = setAutoCommit(autoCommit);
3259                        return b ? "Successfully" : "Connection is null";
3260                } catch (Exception e) {
3261                        log.error(e.getMessage(), e);
3262                        return ScriptConsole.error(e);
3263                }
3264        }
3265
3266        public Object genCreateTables(List<String> params) {
3267            if(!isUseJdbcEnv()){
3268                return "ERROR: JDBC environment is supported only.";
3269            }       
3270                if (params.size() == 0 || params.size() > 2) {
3271                        return "ERROR: Invalid params, eg.'Console.genCreateTables(schema,sqlFilePath) or Console.genCreateTable(sqlFilePath)'";
3272                }
3273                String schema = null;
3274                String sqlFilePath = null;
3275                try {
3276                        if (params.size() == 1) {
3277                                sqlFilePath = formatCommand(params.get(0).trim());
3278                        }
3279                        if (params.size() == 2) {
3280                                schema = formatCommand(params.get(0).trim());
3281                                sqlFilePath = formatCommand(params.get(1).trim());
3282                        }
3283                        return genCreateTables(schema, sqlFilePath);
3284                } catch (Exception e) {
3285                        log.error(e.getMessage(), e);
3286                        return ScriptConsole.error(e);
3287                }
3288        }
3289
3290        public Object genCreateTable(List<String> params) {
3291            if(!isUseJdbcEnv()){
3292                return "ERROR: JDBC environment is supported only.";
3293            }   
3294                if (params.size() == 0 || params.size() > 2) {
3295                        return "ERROR: Invalid params, eg.'Console.genCreateTable(schema,tableName) or Console.genCreateTable(tableName)'";
3296                }
3297                String schema = null;
3298                String tableName = null;
3299                try {
3300                        if (params.size() == 1) {
3301                                tableName = formatCommand(params.get(0).trim());
3302                        }
3303                        if (params.size() == 2) {
3304                                schema = formatCommand(params.get(0).trim());
3305                                tableName = formatCommand(params.get(1).trim());
3306                        }
3307                        return genCreateTable(schema, tableName);
3308                } catch (Exception e) {
3309                        log.error(e.getMessage(), e);
3310                        return ScriptConsole.error(e);
3311                }
3312        }
3313
3314    public static String escapeCsv(String input) {
3315        return EscapeTools.escapeToSingleLineForCsv(input);
3316    }
3317    
3318    public static String unescapeCsv(String input) {
3319        return EscapeTools.unescape(input);
3320    }
3321    
3322}