public static List <R> CreateAnonymousType <R>(ServerResult server_res, Tuple <Dictionary <string, string>, Dictionary <string, short> > def, Ldb _db, List <string> props) { List <R> result = new List <R>(); List <KeyValuePair <int, R> > ordered_result = new List <KeyValuePair <int, R> >(); var data = server_res.SelectEntityResult; var fv = data[data.Keys.First()]; if (fv == null) { return(new List <R>()); } int[] currents = new int[def.Item1.Count() + 1]; int[] currents_ids = new int[def.Item1.Count() + 1]; int id_nr = 0; Tuple <List <int>, List <byte> >[] data_array = new Tuple <List <int>, List <byte> > [def.Item1.Count() + 1]; int c = -1; foreach (var item in def.Item1) { c++; if (item.Key == "Id") { id_nr = c; } currents[c] = 0; currents_ids[c] = 0; } int cc_ = -1; var cc = new Dictionary <string, int>(); foreach (var name in props) { cc_++; if (cc_ == id_nr && name != "Id") { cc_++; } data_array[cc_] = data[name]; cc[name] = cc_; } cc["Id"] = id_nr; data_array[id_nr] = data["Id"]; for (int i = 0; i < server_res.Count; i++) { int id = data_array[id_nr].Item1[currents_ids[id_nr]]; if (!props.Contains("Id")) { currents_ids[id_nr]++; } List <object> cdata = new List <object>(); foreach (var name in props) { int nr = cc[name]; if (!data.ContainsKey(name)) { continue; } var type = _db.StringTypeToLinqType(def.Item1[name]); var by = data_array[nr]; byte[] val = null; bool skip = false; if (currents_ids[nr] >= by.Item1.Count || id < by.Item1[currents_ids[nr]]) { skip = true; } else { currents_ids[nr]++; } if (by.Item2.Any() && !skip) { if (type == LinqDbTypes.int_) { if (by.Item2[currents[nr]] == 1) { currents[nr]++; val = new byte[4]; for (int j = 0; j < 4; j++) { val[j] = by.Item2[currents[nr]]; currents[nr]++; } } else if (by.Item2[currents[nr]] == 250) { currents[nr]++; val = new byte[1]; val[0] = NullConstant[0]; } else { currents[nr]++; } } else if (type == LinqDbTypes.double_ || type == LinqDbTypes.DateTime_) { if (by.Item2[currents[nr]] == 1) { currents[nr]++; val = new byte[8]; for (int j = 0; j < 8; j++) { val[j] = by.Item2[currents[nr]]; currents[nr]++; } } else if (by.Item2[currents[nr]] == 250) { currents[nr]++; val = new byte[1]; val[0] = NullConstant[0]; } else { currents[nr]++; } } else { int size = BitConverter.ToInt32(new byte[4] { by.Item2[currents[nr]], by.Item2[currents[nr] + 1], by.Item2[currents[nr] + 2], by.Item2[currents[nr] + 3] }, 0); currents[nr] += 4; if (size > 0) { val = new byte[size]; for (int j = 0; j < size; j++) { val[j] = by.Item2[currents[nr]]; currents[nr]++; } } else if (size == -2) { val = new byte[1]; val[0] = NullConstant[0]; } } } if (type != LinqDbTypes.binary_ && type != LinqDbTypes.string_) { if (val == null) { switch (type) { case LinqDbTypes.DateTime_: cdata.Add(new DateTime(0001, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)); break; case LinqDbTypes.double_: cdata.Add((double)0); break; case LinqDbTypes.int_: cdata.Add(0); break; default: throw new LinqDbException("Linqdb: Unsupported type"); } } else if (ValsEqual(val, NullConstant)) { cdata.Add(null); } else { switch (type) { case LinqDbTypes.DateTime_: cdata.Add(new DateTime(0001, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(BitConverter.ToDouble(MyReverseWithCopy(val), 0))); break; case LinqDbTypes.double_: cdata.Add(BitConverter.ToDouble(MyReverseWithCopy(val), 0)); break; case LinqDbTypes.int_: int int_v = BitConverter.ToInt32(MyReverseWithCopy(val), 0); cdata.Add(int_v); break; default: throw new LinqDbException("Linqdb: Unsupported type"); } } } else if (type == LinqDbTypes.binary_) { if (val == null || val.Length == 1) { cdata.Add(null); } else { cdata.Add(val.Skip(1).ToArray()); } } else { if (val == null || val.Length == 1) { cdata.Add(null); } else { cdata.Add(Encoding.Unicode.GetString(val.Skip(1).ToArray())); } } } CompiledInfo <R> cinfo = new CompiledInfo <R>(); if (server_res.IsOrdered) { var cresult = _db.CreateType <R>(cinfo, cdata); //if (id != null) //{ ordered_result.Add(new KeyValuePair <int, R>((int)id, cresult)); //} //else //{ // var by = data["Id"]; // currents["Id"] += 1; // byte[] val = new byte[4]; // for (int j = 0; j < 4; j++) // { // val[j] = by[currents["Id"]]; // currents["Id"]++; // } // id = BitConverter.ToInt32(MyReverseWithCopy(val), 0); // ordered_result.Add(new KeyValuePair<int, R>((int)id, cresult)); //} } else { var cresult = _db.CreateType <R>(cinfo, cdata); result.Add(cresult); } } if (server_res.IsOrdered) { result = ordered_result.OrderBy(f => server_res.OrderedIds[f.Key]).Select(f => f.Value).ToList(); } return(result); }
public static List <T> CreateType <T>(ServerResult server_res, Tuple <Dictionary <string, string>, Dictionary <string, short> > def, Ldb _db) where T : new() { List <T> result = new List <T>(); List <KeyValuePair <int, T> > ordered_result = new List <KeyValuePair <int, T> >(); var data = server_res.SelectEntityResult; var fv = data[data.Keys.First()]; if (fv == null || fv.Item2 == null) { return(new List <T>()); } //current_ids fuss is about the fact that any column may have data gaps in multiple places (column added, removed, added ...) //the only column that doesn't have gaps is Id //assumption is that ids in data[name].Item1 is in ascending order int[] currents = new int[def.Item2.Count()]; int[] currents_ids = new int[def.Item2.Count()]; Tuple <List <int>, List <byte> >[] data_array = new Tuple <List <int>, List <byte> > [def.Item2.Count()]; int id_nr = 0; int c = -1; foreach (var name in def.Item2.OrderBy(f => f.Value).Select(f => f.Key)) { c++; if (name == "Id") { id_nr = c; } currents[c] = 0; currents_ids[c] = 0; data_array[c] = data[name]; } for (int i = 0; i < server_res.Count; i++) { int id = data_array[id_nr].Item1[currents_ids[id_nr]]; List <object> cdata = new List <object>(); int cc = -1; foreach (var name in def.Item2.OrderBy(f => f.Value).Select(f => f.Key)) { cc++; var type = _db.StringTypeToLinqType(def.Item1[name]); var by = data_array[cc]; byte[] val = null; bool skip = false; if (currents_ids[cc] >= by.Item1.Count || id < by.Item1[currents_ids[cc]]) { skip = true; } else { currents_ids[cc]++; } if (by.Item2.Any() && !skip) { if (type == LinqDbTypes.int_) { if (by.Item2[currents[cc]] == 1) { currents[cc]++; val = new byte[4]; for (int j = 0; j < 4; j++) { val[j] = by.Item2[currents[cc]]; currents[cc]++; } } else if (by.Item2[currents[cc]] == 250) { currents[cc]++; val = new byte[1]; val[0] = NullConstant[0]; } else { currents[cc]++; } } else if (type == LinqDbTypes.double_ || type == LinqDbTypes.DateTime_) { if (by.Item2[currents[cc]] == 1) { currents[cc]++; val = new byte[8]; for (int j = 0; j < 8; j++) { val[j] = by.Item2[currents[cc]]; currents[cc]++; } } else if (by.Item2[currents[cc]] == 250) { currents[cc]++; val = new byte[1]; val[0] = NullConstant[0]; } else { currents[cc]++; } } else { int size = BitConverter.ToInt32(new byte[4] { by.Item2[currents[cc]], by.Item2[currents[cc] + 1], by.Item2[currents[cc] + 2], by.Item2[currents[cc] + 3] }, 0); currents[cc] += 4; if (size > 0) { val = new byte[size]; for (int j = 0; j < size; j++) { val[j] = by.Item2[currents[cc]]; currents[cc]++; } } else if (size == -2) { val = new byte[1]; val[0] = NullConstant[0]; } } } if (type != LinqDbTypes.binary_ && type != LinqDbTypes.string_) { if (val == null) { switch (type) { case LinqDbTypes.DateTime_: cdata.Add(new DateTime(0001, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)); break; case LinqDbTypes.double_: cdata.Add((double)0); break; case LinqDbTypes.int_: cdata.Add(0); break; default: throw new LinqDbException("Linqdb: Unsupported type"); } } else if (ValsEqual(val, NullConstant)) { cdata.Add(null); } else { switch (type) { case LinqDbTypes.DateTime_: cdata.Add(new DateTime(0001, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(BitConverter.ToDouble(MyReverseWithCopy(val), 0))); break; case LinqDbTypes.double_: cdata.Add(BitConverter.ToDouble(MyReverseWithCopy(val), 0)); break; case LinqDbTypes.int_: int int_v = BitConverter.ToInt32(MyReverseWithCopy(val), 0); //if (name == "Id") //{ // id = int_v; //} cdata.Add(int_v); break; default: throw new LinqDbException("Linqdb: Unsupported type"); } } } else if (type == LinqDbTypes.binary_) { if (val == null || val.Length == 1) { cdata.Add(null); } else { cdata.Add(val.Skip(1).ToArray()); } } else { if (val == null || val.Length == 1) { cdata.Add(null); } else { cdata.Add(Encoding.Unicode.GetString(val.Skip(1).ToArray())); } } } if (server_res.IsOrdered) { var cresult = new T(); int j = 0; var ps = typeof(T).GetProperties().ToDictionary(f => f.Name, z => z); foreach (var propInfo in def.Item2.OrderBy(f => f.Value).Select(f => f.Key)) { ps[propInfo].SetValue(cresult, cdata[j]); j++; } ordered_result.Add(new KeyValuePair <int, T>(id, cresult)); } else { var cresult = new T(); int j = 0; var ps = typeof(T).GetProperties().ToDictionary(f => f.Name, z => z); foreach (var propInfo in def.Item2.OrderBy(f => f.Value).Select(f => f.Key)) { ps[propInfo].SetValue(cresult, cdata[j]); j++; } result.Add(cresult); } } if (server_res.IsOrdered) { result = ordered_result.OrderBy(f => server_res.OrderedIds[f.Key]).Select(f => f.Value).ToList(); } return(result); }
public static List <R> CreateGrouppedAnonymousType <R>(ServerResult server_res, Tuple <Dictionary <string, string>, Dictionary <string, short> > def, Ldb _db, List <string> props) { CompiledInfo <R> cinfo = new CompiledInfo <R>(); var cdata = server_res.SelectGroupResult; HashSet <int> distinct_groups = new HashSet <int>(cdata.Select(f => f.Key)); List <R> result = new List <R>(); foreach (var gr in distinct_groups) { var cresult = _db.CreateType <R>(cinfo, cdata[gr]); result.Add(cresult); } return(result); }