public static DbValue REVERSE(DbFunctionTools tools, DbFunctionArguments args) { string FunctionName = "REVERSE"; args.EnsureCount(FunctionName, 1); DbType arg0type; ByteSlice arg0 = args[0].Eval(out arg0type); if (Types.IsNullValue(arg0)) { return(tools.AllocNullValue()); // Give a null, take a null. } if (arg0type.ID != DbTypeID.CHARS) { args.Expected(FunctionName, 0, "input CHAR(n), got " + arg0type.Name.ToUpper()); } mstring x = tools.GetString(arg0); mstring r = mstring.Prepare(); for (int i = x.Length - 1; i >= 0; i--) { r = r.AppendM(x.SubstringM(i, 1)); } return(tools.AllocValue(r)); }
public static DbValue LEFT(DbFunctionTools tools, DbFunctionArguments args) { string FunctionName = "LEFT"; args.EnsureCount(FunctionName, 2); DbType arg0type; ByteSlice arg0 = args[0].Eval(out arg0type); if (Types.IsNullValue(arg0)) { return(tools.AllocNullValue()); // Give a null, take a null. } if (arg0type.ID != DbTypeID.CHARS) { args.Expected(FunctionName, 0, "input CHAR(n), got " + arg0type.Name.ToUpper()); } DbType arg1type; ByteSlice arg1 = args[1].Eval(out arg1type); if (arg1type.ID != DbTypeID.INT) { args.Expected(FunctionName, 1, "count INT, got " + arg1type.Name.ToUpper()); } mstring x = tools.GetString(arg0); int LeftCount = tools.GetInt(arg1); if (LeftCount >= x.Length) { // User requested the whole string. return(tools.AllocValue(arg0, arg0type)); } else if (LeftCount < 0) { throw new ArgumentException(FunctionName + " count cannot be negative"); } else { x = x.SubstringM(0, LeftCount); return(tools.AllocValue(x)); } }
public static DbValue CHARINDEX(DbFunctionTools tools, DbFunctionArguments args) { string FunctionName = "CHARINDEX"; args.EnsureMinCount(FunctionName, 2); int index = -1; DbType arg0type; ByteSlice arg0 = args[0].Eval(out arg0type); DbType arg1type; ByteSlice arg1 = args[1].Eval(out arg1type); if (Types.IsNullValue(arg0) || Types.IsNullValue(arg1)) { return(tools.AllocValue(index)); } if (arg0type.ID != DbTypeID.CHARS) { args.Expected(FunctionName, 0, "input CHAR(n), got " + arg0type.Name.ToUpper()); return(null); } if (arg1type.ID != DbTypeID.CHARS) { args.Expected(FunctionName, 0, "input CHAR(n), got " + arg1type.Name.ToUpper()); return(null); } int startIndex = 0; if (args.Length > 2) { DbType arg2type; ByteSlice arg2 = args[2].Eval(out arg2type); if (arg2type.ID != DbTypeID.INT) { args.Expected(FunctionName, 0, "input INT, got " + arg2type.Name.ToUpper()); return(null); } startIndex = tools.GetInt(arg2); if (startIndex < 0) { startIndex = 0; } } mstring word = tools.GetString(arg0); mstring sentence = tools.GetString(arg1); if (startIndex > sentence.Length - 1) { index = -1; } else if (startIndex == 0) { index = sentence.IndexOf(word); } else { mstring partsentence = sentence.SubstringM(startIndex); int ix = partsentence.IndexOf(word); if (ix == -1) { index = -1; } else { index = startIndex + ix; } } return(tools.AllocValue(index)); }
private static DbValue _PAD(string functionName, DbFunctionTools tools, DbFunctionArguments args, bool isLeft) { args.EnsureCount(functionName, 3); DbType arg0type; ByteSlice arg0 = args[0].Eval(out arg0type); if (Types.IsNullValue(arg0)) { return(tools.AllocNullValue()); // Give a null, take a null. } if (arg0type.ID != DbTypeID.CHARS) { args.Expected(functionName, 0, "input CHAR(n), got " + arg0type.Name.ToUpper()); } DbType arg1type; ByteSlice arg1 = args[1].Eval(out arg1type); if (Types.IsNullValue(arg1)) { return(tools.AllocNullValue()); // Give a null, take a null. } if (arg1type.ID != DbTypeID.INT) { args.Expected(functionName, 0, "input INT, got " + arg1type.Name.ToUpper()); } DbType arg2type; ByteSlice arg2 = args[2].Eval(out arg2type); if (Types.IsNullValue(arg2)) { return(tools.AllocNullValue()); // Give a null, take a null. } if (arg2type.ID != DbTypeID.CHARS) { args.Expected(functionName, 0, "input CHAR(n), got " + arg2type.Name.ToUpper()); } mstring str = tools.GetString(arg0); int totallen = tools.GetInt(arg1); mstring padstr = tools.GetString(arg2); if (str.Length > totallen) { str = str.SubstringM(0, totallen); } else if (str.Length < totallen) { int delta = totallen - str.Length; int padlen = padstr.Length; mstring newstr = mstring.Prepare(); for (int remain = delta; remain > 0;) { newstr = newstr.AppendM(padstr); remain -= padlen; } //if we go over, truncate. if (newstr.Length > delta) { newstr = newstr.SubstringM(0, delta); } if (isLeft) { str = newstr.AppendM(str); } else { str = str.AppendM(newstr); } } return(tools.AllocValue(str)); }
public static DbValue SUBSTRING(DbFunctionTools tools, DbFunctionArguments args) { string FunctionName = "SUBSTRING"; args.EnsureCount(FunctionName, 3); DbType arg0type; ByteSlice arg0 = args[0].Eval(out arg0type); if (Types.IsNullValue(arg0)) { return(tools.AllocNullValue()); // Give a null, take a null. } if (arg0type.ID != DbTypeID.CHARS) { args.Expected(FunctionName, 0, "input CHAR(n), got " + arg0type.Name.ToUpper()); return(null); } DbType arg1type; ByteSlice arg1 = args[1].Eval(out arg1type); if (arg1type.ID != DbTypeID.INT) { args.Expected(FunctionName, 1, "count INT, got " + arg1type.Name.ToUpper()); return(null); } DbType arg2type; ByteSlice arg2 = args[2].Eval(out arg2type); if (arg2type.ID != DbTypeID.INT) { args.Expected(FunctionName, 1, "count INT, got " + arg2type.Name.ToUpper()); return(null); } mstring x = tools.GetString(arg0); int startIndex = tools.GetInt(arg1); if (startIndex < 0) { startIndex = 0; } int len = tools.GetInt(arg2); if (len < 0) { throw new ArgumentException(FunctionName + " length cannot be negative"); } if (startIndex + len > x.Length) { return(tools.AllocValue(mstring.Prepare())); } else { mstring sub = x.SubstringM(startIndex, len); return(tools.AllocValue(sub)); } }
public static DbValue INSTR(DbFunctionTools tools, DbFunctionArguments args) { string FunctionName = "INSTR"; args.EnsureMinCount(FunctionName, 2); DbType arg0type; ByteSlice arg0 = args[0].Eval(out arg0type); if (Types.IsNullValue(arg0)) { return(tools.AllocNullValue()); // Give a null, take a null. } if (arg0type.ID != DbTypeID.CHARS) { args.Expected(FunctionName, 0, "input CHAR(n), got " + arg0type.Name.ToUpper()); } DbType arg1type; ByteSlice arg1 = args[1].Eval(out arg1type); if (Types.IsNullValue(arg1)) { return(tools.AllocNullValue()); // Give a null, take a null. } if (arg1type.ID != DbTypeID.CHARS) { args.Expected(FunctionName, 0, "input CHAR(n), got " + arg1type.Name.ToUpper()); } int startIndex = 0; if (args.Length > 2) { DbType arg2type; ByteSlice arg2 = args[2].Eval(out arg2type); if (arg2type.ID != DbTypeID.INT) { args.Expected(FunctionName, 0, "input INT, got " + arg2type.Name.ToUpper()); } if (!Types.IsNullValue(arg2)) { startIndex = tools.GetInt(arg2); } } mstring sentence = tools.GetString(arg0); mstring word = tools.GetString(arg1); int index = -1; if (startIndex < sentence.Length) { if (startIndex > 0) { sentence = sentence.SubstringM(startIndex); } index = sentence.IndexOf(word); if (index > -1) { index += startIndex; } } return(tools.AllocValue(index)); }
public static DbValue CAST(DbFunctionTools tools, DbFunctionArguments args) { #if DEBUG //System.Diagnostics.Debugger.Launch(); #endif string FunctionName = "CAST"; args.EnsureCount(FunctionName, 2); DbType type; ByteSlice bs = args[0].Eval(out type); mstring xas = tools.GetString(args[1]); if (!xas.StartsWith("AS ")) { #if DEBUG throw new Exception("Expected AS <type> in CAST, not: " + xas); #endif throw new Exception("Expected AS <type> in CAST"); } mstring msastype = xas.SubstringM(3); string sastype = msastype.ToString(); // Alloc. sastype = DbType.NormalizeName(sastype); // Alloc if char(n). DbType astype = DbType.Prepare(sastype); // Alloc if char(n). if (DbTypeID.NULL == astype.ID) { throw new Exception("Unknown AS type in CAST: " + sastype); } switch (astype.ID) { case DbTypeID.INT: switch (type.ID) { case DbTypeID.INT: // as INT if (astype.Size > type.Size) { throw new Exception("CAST: source value buffer too small"); } return(tools.AllocValue(ByteSlice.Prepare(bs, 0, astype.Size), astype)); case DbTypeID.LONG: // as INT return(tools.AllocValue((int)tools.GetLong(bs))); case DbTypeID.DOUBLE: // as INT return(tools.AllocValue((int)tools.GetDouble(bs))); case DbTypeID.DATETIME: // as INT return(tools.AllocValue((int)tools.GetDateTime(bs).Ticks)); case DbTypeID.CHARS: // as INT { int to = tools.GetString(bs).NextItemToInt32(' '); return(tools.AllocValue(to)); } default: throw new Exception("Cannot handle CAST value of type " + type.Name + " AS " + astype.Name); } break; case DbTypeID.LONG: switch (type.ID) { case DbTypeID.INT: // as LONG return(tools.AllocValue((long)tools.GetInt(bs))); case DbTypeID.LONG: // as LONG if (astype.Size > type.Size) { throw new Exception("CAST: source value buffer too small"); } return(tools.AllocValue(ByteSlice.Prepare(bs, 0, astype.Size), astype)); case DbTypeID.DOUBLE: // as LONG return(tools.AllocValue((long)tools.GetDouble(bs))); case DbTypeID.DATETIME: // as LONG return(tools.AllocValue((long)tools.GetDateTime(bs).Ticks)); case DbTypeID.CHARS: // as LONG { long to = tools.GetString(bs).NextItemToInt64(' '); return(tools.AllocValue(to)); } default: throw new Exception("Cannot handle CAST value of type " + type.Name + " AS " + astype.Name); } break; case DbTypeID.DOUBLE: switch (type.ID) { case DbTypeID.INT: // as DOUBLE return(tools.AllocValue((double)tools.GetInt(bs))); case DbTypeID.LONG: // as DOUBLE return(tools.AllocValue((double)tools.GetLong(bs))); case DbTypeID.DOUBLE: // as DOUBLE if (astype.Size > type.Size) { throw new Exception("CAST: source value buffer too small"); } return(tools.AllocValue(ByteSlice.Prepare(bs, 0, astype.Size), astype)); case DbTypeID.DATETIME: // as DOUBLE return(tools.AllocValue((double)tools.GetDateTime(bs).Ticks)); case DbTypeID.CHARS: // as DOUBLE { double to = tools.GetString(bs).NextItemToDouble(' '); return(tools.AllocValue(to)); } default: throw new Exception("Cannot handle CAST value of type " + type.Name + " AS " + astype.Name); } break; case DbTypeID.DATETIME: switch (type.ID) { case DbTypeID.INT: // as DATETIME return(tools.AllocValue(new DateTime((long)tools.GetInt(bs)))); case DbTypeID.LONG: // as DATETIME return(tools.AllocValue(new DateTime((long)tools.GetLong(bs)))); case DbTypeID.DOUBLE: // as DATETIME return(tools.AllocValue(new DateTime((long)tools.GetDouble(bs)))); case DbTypeID.DATETIME: // as DATETIME if (astype.Size > type.Size) { throw new Exception("CAST: source value buffer too small"); } return(tools.AllocValue(ByteSlice.Prepare(bs, 0, astype.Size), astype)); case DbTypeID.CHARS: // as DATETIME { mstring to = tools.GetString(bs); return(tools.AllocValue(DateTime.Parse(to.ToString()))); } default: throw new Exception("Cannot handle CAST value of type " + type.Name + " AS " + astype.Name); } break; case DbTypeID.CHARS: switch (type.ID) { case DbTypeID.INT: // as CHAR(n) { mstring ms = mstring.Prepare(tools.GetInt(bs)); return(tools.AllocValue(ms, astype.Size)); } case DbTypeID.LONG: // as CHAR(n) { mstring ms = mstring.Prepare(tools.GetLong(bs)); return(tools.AllocValue(ms, astype.Size)); } case DbTypeID.DOUBLE: // as CHAR(n) { mstring ms = mstring.Prepare(tools.GetDouble(bs)); return(tools.AllocValue(ms, astype.Size)); } case DbTypeID.DATETIME: // as CHAR(n) { mstring ms = mstring.Prepare(tools.GetDateTime(bs).ToString()); return(tools.AllocValue(ms, astype.Size)); } case DbTypeID.CHARS: // as CHAR(n) if (astype.Size > type.Size) { //throw new Exception("CAST: source value buffer too small"); return(tools.AllocValue(tools.GetString(bs), astype.Size)); } return(tools.AllocValue(ByteSlice.Prepare(bs, 0, astype.Size), astype)); default: throw new Exception("Cannot handle CAST value of type " + type.Name + " AS " + astype.Name); } break; default: throw new Exception("Cannot handle CAST value of type " + type.Name + " AS " + astype.Name); } }