A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/signumsoftware/framework/commit/160ddc3b3261c544b15c144c4d2e47f04b305feb below:

Merge remote-tracking branch 'tfs/liteModel' · signumsoftware/framework@160ddc3 · GitHub

1 +

using Signum.Utilities.Reflection;

2 +

using Signum.Engine.Linq;

3 +

using System.Data;

4 +

using Signum.Entities.Internal;

5 +

using Signum.Engine.Connection;

6 + 7 +

namespace Signum.Engine.Cache;

8 + 9 +

class CachedLiteTable<T> : CachedTableBase where T : Entity

10 +

{

11 +

public override IColumn? ParentColumn { get; set; }

12 + 13 +

Table table;

14 + 15 +

Alias currentAlias;

16 +

string lastPartialJoin;

17 +

string? remainingJoins;

18 + 19 +

Func<FieldReader, object> rowReader = null!;

20 +

ResetLazy<Dictionary<PrimaryKey, object>> rows = null!;

21 +

Func<object, PrimaryKey> idGetter;

22 +

Dictionary<Type, ICachedLiteModelConstructor> liteModelConstructors = null!;

23 + 24 +

SemiCachedController<T>? semiCachedController;

25 + 26 +

public Dictionary<PrimaryKey, object> GetRows()

27 +

{

28 +

return rows.Value;

29 +

}

30 + 31 +

public CachedLiteTable(ICacheLogicController controller, AliasGenerator aliasGenerator, string lastPartialJoin, string? remainingJoins)

32 +

: base(controller)

33 +

{

34 +

this.table = Schema.Current.Table(typeof(T));

35 + 36 +

HashSet<IColumn> columns = new HashSet<IColumn> { table.PrimaryKey };

37 + 38 +

foreach (var modelType in Lite.GetAllLiteModelTypes(typeof(T)))

39 +

{

40 +

var modelConstructor = Lite.GetModelConstructorExpression(typeof(T), modelType);

41 + 42 +

ToStringColumnsFinderVisitor.GatherColumns(modelConstructor, this.table, columns);

43 +

}

44 + 45 +

var ctr = this.Constructor = new CachedTableConstructor(this, aliasGenerator, columns.ToList());

46 + 47 +

this.lastPartialJoin = lastPartialJoin;

48 +

this.remainingJoins = remainingJoins;

49 +

this.currentAlias = aliasGenerator.NextTableAlias(table.Name.Name);

50 +

var isPostgres = Schema.Current.Settings.IsPostgres;

51 + 52 +

//Query

53 +

using (ObjectName.OverrideOptions(new ObjectNameOptions { AvoidDatabaseName = true }))

54 +

{

55 +

string select = "SELECT {0}\r\nFROM {1} {2}\r\n".FormatWith(

56 +

ctr.columns.ToString(c => currentAlias + "." + c.Name.SqlEscape(isPostgres), ", "),

57 +

table.Name.ToString(),

58 +

currentAlias.ToString());

59 + 60 +

select += this.lastPartialJoin + currentAlias + "." + table.PrimaryKey.Name.SqlEscape(isPostgres) + "\r\n" + this.remainingJoins;

61 + 62 +

query = new SqlPreCommandSimple(select);

63 +

}

64 + 65 +

//Reader

66 +

{

67 +

rowReader = ctr.GetRowReader();

68 + 69 +

idGetter = ctr.GetPrimaryKeyGetter((IColumn)table.PrimaryKey);

70 +

}

71 + 72 +

rows = new ResetLazy<Dictionary<PrimaryKey, object>>(() =>

73 +

{

74 +

return SqlServerRetry.Retry(() =>

75 +

{

76 +

CacheLogic.AssertSqlDependencyStarted();

77 + 78 +

Dictionary<PrimaryKey, object> result = new Dictionary<PrimaryKey, object>();

79 + 80 +

using (MeasureLoad())

81 +

using (Connector.Override(Connector.Current.ForDatabase(table.Name.Schema?.Database)))

82 +

using (var tr = Transaction.ForceNew(IsolationLevel.ReadCommitted))

83 +

{

84 +

if (CacheLogic.LogWriter != null)

85 +

CacheLogic.LogWriter.WriteLine("Load {0}".FormatWith(GetType().TypeName()));

86 + 87 +

Connector.Current.ExecuteDataReaderOptionalDependency(query, OnChange, fr =>

88 +

{

89 +

var obj = rowReader(fr);

90 +

result[idGetter(obj)] = obj; //Could be repeated joins

91 +

});

92 +

tr.Commit();

93 +

}

94 + 95 +

return result;

96 +

});

97 +

}, mode: LazyThreadSafetyMode.ExecutionAndPublication);

98 + 99 +

if (!CacheLogic.WithSqlDependency) //Always semi

100 +

{

101 +

semiCachedController = new SemiCachedController<T>(this);

102 +

}

103 +

}

104 + 105 +

public override void SchemaCompleted()

106 +

{

107 +

this.liteModelConstructors = Lite.GetAllLiteModelTypes(typeof(T))

108 +

.ToDictionary(modelType => modelType, modelType =>

109 +

{

110 +

var modelConstructor = Lite.GetModelConstructorExpression(typeof(T), modelType);

111 +

var cachedModelConstructor = LiteModelExpressionVisitor.giGetCachedLiteModelConstructor.GetInvoker(typeof(T), modelType)(this.Constructor, modelConstructor);

112 +

return cachedModelConstructor;

113 +

});

114 + 115 +

if (this.subTables != null)

116 +

foreach (var item in this.subTables)

117 +

item.SchemaCompleted();

118 +

}

119 + 120 +

protected override void Reset()

121 +

{

122 +

if (rows == null)

123 +

return;

124 + 125 +

if (CacheLogic.LogWriter != null )

126 +

CacheLogic.LogWriter.WriteLine((rows.IsValueCreated ? "RESET {0}" : "Reset {0}").FormatWith(GetType().TypeName()));

127 + 128 +

rows.Reset();

129 +

}

130 + 131 +

protected override void Load()

132 +

{

133 +

if (rows == null)

134 +

return;

135 + 136 +

rows.Load();

137 +

}

138 + 139 + 140 +

public Lite<T> GetLite(PrimaryKey id, IRetriever retriever, Type modelType)

141 +

{

142 +

Interlocked.Increment(ref hits);

143 + 144 +

var model = liteModelConstructors.GetOrThrow(modelType).GetModel(id, retriever);

145 + 146 +

var lite = Lite.Create<T>(id, model);

147 +

retriever.ModifiablePostRetrieving((LiteImp)lite);

148 +

return lite;

149 +

}

150 + 151 +

public override int? Count

152 +

{

153 +

get { return rows.IsValueCreated ? rows.Value.Count : (int?)null; }

154 +

}

155 + 156 +

public override Type Type

157 +

{

158 +

get { return typeof(Lite<T>); }

159 +

}

160 + 161 +

public override ITable Table

162 +

{

163 +

get { return table; }

164 +

}

165 + 166 +

class ToStringColumnsFinderVisitor : ExpressionVisitor

167 +

{

168 +

ParameterExpression param;

169 + 170 +

HashSet<IColumn> columns;

171 + 172 +

Table table;

173 + 174 +

public ToStringColumnsFinderVisitor(ParameterExpression param, HashSet<IColumn> columns, Table table)

175 +

{

176 +

this.param = param;

177 +

this.columns = columns;

178 +

this.table = table;

179 +

}

180 + 181 +

public static Expression GatherColumns(LambdaExpression lambda, Table table, HashSet<IColumn> columns)

182 +

{

183 +

ToStringColumnsFinderVisitor toStr = new ToStringColumnsFinderVisitor(

184 +

lambda.Parameters.SingleEx(),

185 +

columns,

186 +

table

187 +

);

188 + 189 +

var result = toStr.Visit(lambda.Body);

190 + 191 +

return result;

192 +

}

193 + 194 + 195 + 196 +

static MethodInfo miMixin = ReflectionTools.GetMethodInfo((Entity e) => e.Mixin<MixinEntity>()).GetGenericMethodDefinition();

197 + 198 +

protected override Expression VisitMember(MemberExpression node)

199 +

{

200 +

if (node.Expression == param)

201 +

{

202 +

var field = table.GetField(node.Member);

203 +

var column = GetColumn(field);

204 +

columns.Add(column);

205 +

return node;

206 +

}

207 + 208 +

if (node.Expression is MethodCallExpression me && me.Method.IsInstantiationOf(miMixin))

209 +

{

210 +

var type = me.Method.GetGenericArguments()[0];

211 +

var mixin = table.Mixins!.GetOrThrow(type);

212 +

var field = mixin.GetField(node.Member);

213 +

var column = GetColumn(field);

214 +

columns.Add(column);

215 +

return node;

216 +

}

217 + 218 +

return base.VisitMember(node);

219 +

}

220 + 221 +

protected override Expression VisitMethodCall(MethodCallExpression node)

222 +

{

223 +

var obj = base.Visit(node.Object);

224 +

var args = base.Visit(node.Arguments);

225 + 226 +

LambdaExpression? lambda = ExpressionCleaner.GetFieldExpansion(obj?.Type, node.Method);

227 + 228 +

if (lambda != null)

229 +

{

230 +

var replace = ExpressionReplacer.Replace(Expression.Invoke(lambda, obj == null ? args : args.PreAnd(obj)));

231 + 232 +

return this.Visit(replace);

233 +

}

234 + 235 +

if (node.Object == param && node.Method.Name == nameof(node.ToString))

236 +

{

237 +

columns.Add(this.table.ToStrColumn!);

238 +

return node;

239 +

}

240 + 241 +

return base.VisitMethodCall(node);

242 +

}

243 + 244 +

private IColumn GetColumn(Field field)

245 +

{

246 +

if (field is FieldPrimaryKey || field is FieldValue || field is FieldTicks)

247 +

return (IColumn)field;

248 + 249 +

throw new InvalidOperationException("{0} not supported when caching the ToString for a Lite of a transacional entity ({1})".FormatWith(field.GetType().TypeName(), this.table.Type.TypeName()));

250 +

}

251 +

}

252 + 253 +

internal override bool Contains(PrimaryKey primaryKey)

254 +

{

255 +

return this.rows.Value.ContainsKey(primaryKey);

256 +

}

257 +

}


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4