123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- using System;
- using System.IO;
- using System.Linq;
- using System.Linq.Expressions;
- using System.Threading;
- using InABox.Clients;
- using InABox.Core;
- using System.Diagnostics.CodeAnalysis;
- namespace InABox.Mobile
- {
- public abstract class DetailModel<TParent, TItem, TEntity> : Model<TParent,TItem,TEntity>, IDetailModel<TParent, TItem, TEntity>
- where TParent : DetailModel<TParent, TItem, TEntity>, IModel
- where TEntity : Entity, IRemotable, IPersistent, new()
- where TItem : Shell<TParent, TEntity>, new()
- {
- protected DetailModel(IModelHost host, Func<Filter<TEntity>> filter, bool transient = false) : base(host, filter, transient)
- {
- }
- protected DetailModel(IModelHost host, Func<Filter<TEntity>> filter, [NotNull] String filename) : base(host, filter, filename)
- {
- }
-
- protected override void Initialize()
- {
- Filter = null;
- Item = null;
- }
-
- private TItem _item;
- public TItem Item
- {
- get => _item;
- set => SetProperty(ref _item, value);
- }
-
- protected virtual Expression<Func<TEntity, object>> ImageColumn { get; }
- private void DoBeforeLoad(MultiQuery query)
- {
- if (ImageColumn != null)
- query.Add<Document>(
- new Filter<Document>(x => x.ID).InQuery<TEntity>(Filter(),ImageColumn),
- new Columns<Document>(x=>x.ID).Add(x=>x.Data)
- );
- BeforeLoad(query);
- }
-
- public override void BeforeLoad(MultiQuery query)
- {
-
- }
- private void DoAfterLoad(MultiQuery query, Action loaded = null)
- {
- if (ImageColumn != null)
- {
- Images.Clear();
- query.Get<Document>().IntoDictionary<Document, Guid, byte[]>(Images, x => x.ID,
- r => r.Get<Document, byte[]>(x => x.Data));
- }
- AfterLoad(query);
- Loaded = true;
- loaded?.Invoke();
- NotifyChanged();
- }
-
- public override void AfterLoad(MultiQuery query)
- {
- }
- private TItem CreateItemFromEntity(TEntity entity)
- {
- CoreTable table = new CoreTable();
- table.LoadColumns(GetColumns<TItem,TEntity>());
- CoreRow row = table.NewRow();
- if (entity != null)
- table.LoadRow(row, entity);
- var item = new TItem() { Row = row, Parent = this as TParent };
- item.PropertyChanged += DoPropertyChanged;
- return item;
- }
-
- private TItem CreateItemFromRow(CoreRow row)
- {
- var item = (row != null)
- ? new TItem() { Row = row, Parent = this as TParent }
- : CreateItemFromEntity(null);
- item.PropertyChanged += DoPropertyChanged;
- return item;
- }
- public void Load(TEntity entity, Action loaded = null)
- {
- Filter = () => new Filter<TEntity>(x => x.ID).IsEqualTo(entity.ID);
- MultiQuery query = new MultiQuery();
-
- DoBeforeLoad(query);
- Item = CreateItemFromEntity(entity);
- if (loaded != null)
- query.Query((q) => DoAfterLoad(q, loaded));
- else
- {
- query.Query();
- DoAfterLoad(query);
- }
- }
-
- public override void Load(Action loaded = null)
- {
-
- MultiQuery query = new MultiQuery();
-
- query.Add(
- Filter(),
- GetColumns<TItem,TEntity>()
- );
-
- DoBeforeLoad(query);
-
- if (Host.IsConnected())
- {
- if (loaded != null)
- query.Query((q) =>
- {
- if (Type == ModelType.Persistent)
- SaveToStorage(query);
- Item = CreateItemFromRow(q.Get<TEntity>().Rows.FirstOrDefault());
- DoAfterLoad(q, loaded);
- });
- else
- {
- query.Query();
- if (Type == ModelType.Persistent)
- SaveToStorage(query);
- Item = CreateItemFromRow(query.Get<TEntity>().Rows.FirstOrDefault());
- DoAfterLoad(query);
- }
- }
- else
- {
- if (Type == ModelType.Transient)
- {
- InitializeTables(query);
- }
- else if (Type == ModelType.Normal)
- {
- // Only load
- if (_item == null)
- InitializeTables(query);
- }
- else if (Type == ModelType.Persistent)
- {
- // Treat it as normal, unless its the first time through
- // in which case try to load it from storage, if the
- // data has been previously cached
- if (_item == null)
- LoadFromStorage(query);
- }
- Item = CreateItemFromRow(query.Get<TEntity>().Rows.FirstOrDefault());
- DoAfterLoad(query, loaded);
- }
- }
-
- protected virtual void BeforeSave(TItem item)
- {
-
- }
-
- protected virtual void AfterSave(TItem item)
- {
-
- }
-
- public void Save(String auditmessage)
- {
- BeforeSave(Item);
- new Client<TEntity>().Save(Item.Entity,auditmessage);
- AfterSave(Item);
- }
-
- public override IModel Refresh(bool force)
- {
- if (!Loaded || force)
- Load();
- return this;
- }
-
- public override void Refresh(bool force, Action loaded)
- {
- if (!Loaded || force)
- Load(loaded);
- else
- loaded?.Invoke();
- }
- }
- }
|