1 /*
2  * Copyright 2015-2018 HuntLabs.cn
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 module hunt.sql.visitor.functions.Substring;
17 
18 // import hunt.sql.visitor.SQLEvalVisitor.EVAL_VALUE;
19 
20 import hunt.collection;
21 
22 import hunt.sql.ast.SQLExpr;
23 import hunt.sql.ast.expr.SQLMethodInvokeExpr;
24 import hunt.sql.visitor.SQLEvalVisitor;
25 import hunt.sql.visitor.functions.Function;
26 import hunt.Number;
27 import hunt.String;
28 import hunt.String;
29 import hunt.collection;
30 import std.conv;
31 import std.uni;
32 import hunt.text;
33 
34 import std.concurrency : initOnce;
35 
36 public class Substring : Function {
37 
38     static Substring instance() {
39         __gshared Substring inst;
40         return initOnce!inst(new Substring());
41     } 
42     
43     // public  static Substring instance;
44 
45     // static this()
46     // {
47     //     instance = new Substring();
48     // }
49 
50     public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
51         List!(SQLExpr) params = x.getParameters();
52         int paramSize = params.size();
53 
54         SQLExpr param0 = params.get(0);
55 
56         SQLExpr param1;
57         if (paramSize == 1 && x.getFrom() !is null) {
58             param1 = x.getFrom();
59             paramSize = 2;
60         } else if (paramSize != 2 && paramSize != 3) {
61             return cast(Object)(SQLEvalVisitor.EVAL_ERROR);
62         } else {
63             param1 = params.get(1);
64         }
65 
66         param0.accept(visitor);
67         param1.accept(visitor);
68 
69         Object param0Value = param0.getAttributes().get(SQLEvalVisitor.EVAL_VALUE);
70         Object param1Value = param1.getAttributes().get(SQLEvalVisitor.EVAL_VALUE);
71         if (param0Value is null || param1Value is null) {
72             return cast(Object)(SQLEvalVisitor.EVAL_ERROR);
73         }
74 
75         string str = param0Value.toString();
76         int index = (cast(Number) param1Value).intValue();
77 
78         if (paramSize == 2 && x.getFor() is null) {
79             if (index <= 0) {
80                 int lastIndex = cast(int)(str.length) + index;
81                 return new String(str.substring(lastIndex));
82             }
83 
84             return new String(str.substring(index - 1));
85         }
86 
87         SQLExpr param2 = x.getFor();
88         if (param2 is null && params.size() > 2) {
89             param2 = params.get(2);
90         }
91         param2.accept(visitor);
92         Object param2Value = param2.getAttributes().get(SQLEvalVisitor.EVAL_VALUE);
93         if (param2Value is null) {
94             return cast(Object)(SQLEvalVisitor.EVAL_ERROR);
95         }
96 
97         int len = (cast(Number) param2Value).intValue();
98 
99         string result;
100         if (index <= 0) {
101             int lastIndex = cast(int)(str.length) + index;
102             result = str.substring(lastIndex);
103         } else {
104             result = str.substring(index - 1);
105         }
106 
107         if (len > result.length) {
108             return new String(result);
109         }
110         return new String(result.substring(0, len));
111     }
112 }