/// <summary> /// Initialize connection string parsing string in "key1=value1;key2=value2;...." format or only "filename" as default (when no ; char found) /// </summary> public ConnectionString(string connectionString) : this() { if (string.IsNullOrEmpty(connectionString)) { throw new ArgumentNullException(nameof(connectionString)); } // create a dictionary from string name=value collection if (connectionString.Contains("=")) { _values.ParseKeyValue(connectionString); } else { _values["filename"] = connectionString; } // setting values to properties this.Connection = _values.GetValue("connection", this.Connection); this.Filename = _values.GetValue("filename", this.Filename).Trim(); this.Password = _values.GetValue("password", this.Password); if (this.Password == string.Empty) { this.Password = null; } this.InitialSize = _values.GetFileSize(@"initial size", this.InitialSize); this.ReadOnly = _values.GetValue("readonly", this.ReadOnly); this.Collation = _values.ContainsKey("collation") ? new Collation(_values.GetValue <string>("collation")) : this.Collation; this.Upgrade = _values.GetValue("upgrade", this.Upgrade); }
public static BsonValue IN_ALL(Collation collation, IEnumerable <BsonValue> left, BsonValue right) => left.All(x => IN(collation, x, right));
public static BsonValue BETWEEN_ANY(Collation collation, IEnumerable <BsonValue> left, BsonValue right) => left.Any(x => BETWEEN(collation, x, right));
public static BsonValue LIKE_ANY(Collation collation, IEnumerable <BsonValue> left, BsonValue right) => left.Any(x => LIKE(collation, x, right));
public static BsonValue NEQ_ALL(Collation collation, IEnumerable <BsonValue> left, BsonValue right) => left.Any(x => !collation.Equals(x, right));
/// <summary> /// Test if left and right are not same value. Returns true or false /// </summary> public static BsonValue NEQ(Collation collation, BsonValue left, BsonValue right) => !collation.Equals(left, right);
public static BsonValue LTE_ALL(Collation collation, IEnumerable <BsonValue> left, BsonValue right) => left.Any(x => collation.Compare(x, right) <= 0);
/// <summary> /// Create new instance of LiteDatabase using an external Stream source as database file /// </summary> public LiteDatabase(Stream stream, Collation collation = null, BsonMapper mapper = null) { _engine = new LiteEngine(stream, collation); _mapper = mapper ?? BsonMapper.Global; }
public static BsonValue GT_ANY(Collation collation, IEnumerable <BsonValue> left, BsonValue right) => left.Any(x => collation.Compare(x, right) > 0);
public static BsonValue DATE_UTC(Collation collation, BsonValue value) => DATETIME_UTC(collation, value);
public static IEnumerable <BsonValue> SORT(BsonDocument root, Collation collation, BsonDocument parameters, IEnumerable <BsonValue> input, BsonExpression sortExpr) { return(SORT(root, collation, parameters, input, sortExpr, order: 1)); }
/// <summary> /// Implement SqlLike in C# string - based on /// https://stackoverflow.com/a/8583383/3286260 /// I remove support for [ and ] to avoid missing close brackets /// </summary> public static bool SqlLike(this string str, string pattern, Collation collation) { var isMatch = true; var isWildCardOn = false; var isCharWildCardOn = false; var isCharSetOn = false; var isNotCharSetOn = false; var endOfPattern = false; var lastWildCard = -1; var patternIndex = 0; var p = '\0'; for (var i = 0; i < str.Length; i++) { var c = str[i]; endOfPattern = (patternIndex >= pattern.Length); if (!endOfPattern) { p = pattern[patternIndex]; if (!isWildCardOn && p == '%') { lastWildCard = patternIndex; isWildCardOn = true; while (patternIndex < pattern.Length && pattern[patternIndex] == '%') { patternIndex++; } if (patternIndex >= pattern.Length) { p = '\0'; } else { p = pattern[patternIndex]; } } else if (p == '_') { isCharWildCardOn = true; patternIndex++; } } if (isWildCardOn) { if (char.ToUpper(c) == char.ToUpper(p)) { isWildCardOn = false; patternIndex++; } } else if (isCharWildCardOn) { isCharWildCardOn = false; } else if (isCharSetOn || isNotCharSetOn) { //var charMatch = (set.Contains(char.ToUpper(c))); // -- always "false" - remove [abc] support //if ((isNotCharSetOn && charMatch) || (isCharSetOn && !charMatch)) if (isCharSetOn) { if (lastWildCard >= 0) { patternIndex = lastWildCard; } else { isMatch = false; break; } } isNotCharSetOn = isCharSetOn = false; } else { if (collation.Compare(c, p) == 0) { patternIndex++; } else { if (lastWildCard >= 0) { patternIndex = lastWildCard; } else { isMatch = false; break; } } } } endOfPattern = (patternIndex >= pattern.Length); if (isMatch && !endOfPattern) { var isOnlyWildCards = true; for (var i = patternIndex; i < pattern.Length; i++) { if (pattern[i] != '%') { isOnlyWildCards = false; break; } } if (isOnlyWildCards) { endOfPattern = true; } } return(isMatch && endOfPattern); }
/// <summary> /// Execute expression and returns IEnumerable values - returns NULL if no elements /// </summary> internal BsonValue ExecuteScalar(IEnumerable <BsonDocument> source, BsonDocument root, BsonValue current, Collation collation) { if (this.IsScalar) { return(_funcScalar(source, root, current, collation ?? Collation.Binary, this.Parameters)); } else { throw new LiteException(0, $"Expression `{this.Source}` is not a scalar expression and can return more than one result"); } }
/// <summary> /// Execute expression over document to get all index keys. /// Return distinct value (no duplicate key to same document) /// </summary> internal IEnumerable <BsonValue> GetIndexKeys(BsonDocument doc, Collation collation) { return(this.Execute(doc, collation).Distinct()); }
/// <summary> /// Execute expression and returns IEnumerable values - returns NULL if no elements /// </summary> internal IEnumerable <BsonValue> Execute(IEnumerable <BsonDocument> source, BsonDocument root, BsonValue current, Collation collation) { if (this.IsScalar) { var value = _funcScalar(source, root, current, collation ?? Collation.Binary, this.Parameters); yield return(value); } else { var values = _funcEnumerable(source, root, current, collation ?? Collation.Binary, this.Parameters); foreach (var value in values) { yield return(value); } } }
/// <summary> /// Returns a single value from array according index or expression parameter /// </summary> public static BsonValue ARRAY_INDEX(BsonValue value, int index, BsonExpression expr, BsonDocument root, Collation collation, BsonDocument parameters) { if (!value.IsArray) { return(BsonValue.Null); } var arr = value.AsArray; // for expr.Type = parameter, just get value as index (fixed position) if (expr.Type == BsonExpressionType.Parameter) { // update parameters in expression parameters.CopyTo(expr.Parameters); // get fixed position based on parameter value (must return int value) var indexValue = expr.ExecuteScalar(root, collation); if (!indexValue.IsNumber) { throw new LiteException(0, "Parameter expression must return number when called inside an array"); } index = indexValue.AsInt32; } var idx = index < 0 ? arr.Count + index : index; if (arr.Count > idx) { return(arr[idx]); } return(BsonValue.Null); }
/// <summary> /// Returns all values from array according filter expression or all values (index = MaxValue) /// </summary> public static IEnumerable <BsonValue> ARRAY_FILTER(BsonValue value, int index, BsonExpression filterExpr, BsonDocument root, Collation collation, BsonDocument parameters) { if (!value.IsArray) { yield break; } var arr = value.AsArray; // [*] - index are all values if (index == int.MaxValue) { foreach (var item in arr) { yield return(item); } } // [<expr>] - index are an expression else { // update parameters in expression parameters.CopyTo(filterExpr.Parameters); foreach (var item in arr) { // execute for each child value and except a first bool value (returns if true) var c = filterExpr.ExecuteScalar(new BsonDocument[] { root }, root, item, collation); if (c.IsBoolean && c.AsBoolean == true) { yield return(item); } } } }
/// <summary> /// Test if left is less or equals than right value. Returns true or false /// </summary> public static BsonValue LTE(Collation collation, BsonValue left, BsonValue right) => left <= right;