PageRenderTime 38ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/Raven.Studio/Models/DatabaseModel.cs

http://github.com/ayende/ravendb
C# | 234 lines | 200 code | 34 blank | 0 comment | 15 complexity | 840f681f775f0ca6242245d0506ca6fe MD5 | raw file
Possible License(s): GPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-2.1, Apache-2.0, BSD-3-Clause, CC-BY-SA-3.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Reactive;
  5. using System.Reactive.Disposables;
  6. using System.Reactive.Subjects;
  7. using System.Windows.Media.Imaging;
  8. using Raven.Abstractions.Data;
  9. using Raven.Abstractions.Replication;
  10. using Raven.Bundles.Replication.Data;
  11. using Raven.Client.Changes;
  12. using Raven.Client.Connection.Async;
  13. using Raven.Client.Document;
  14. using Raven.Json.Linq;
  15. using Raven.Studio.Features.Tasks;
  16. using Raven.Studio.Infrastructure;
  17. using System.Linq;
  18. using System.Reactive.Linq;
  19. using Raven.Studio.Extensions;
  20. namespace Raven.Studio.Models
  21. {
  22. public class DatabaseModel : Model, IDisposable
  23. {
  24. private readonly IAsyncDatabaseCommands asyncDatabaseCommands;
  25. private readonly string name;
  26. private readonly DocumentStore documentStore;
  27. private IObservable<DocumentChangeNotification> documentChanges;
  28. private IObservable<IndexChangeNotification> indexChanges;
  29. private readonly CompositeDisposable disposable = new CompositeDisposable();
  30. private IDatabaseChanges databaseChanges;
  31. private Observable<string> status;
  32. public Observable<TaskModel> SelectedTask { get; set; }
  33. public Observable<DatabaseDocument> DatabaseDocument { get; set; }
  34. public QueueModel<string> RecentDocuments
  35. {
  36. get
  37. {
  38. if (ApplicationModel.Current.Server.Value.RecentDocuments.ContainsKey(Name) == false)
  39. ApplicationModel.Current.Server.Value.RecentDocuments[name] = new QueueModel<string>(5);
  40. return ApplicationModel.Current.Server.Value.RecentDocuments[Name];
  41. }
  42. }
  43. public DatabaseModel(string name, DocumentStore documentStore)
  44. {
  45. this.name = name;
  46. this.documentStore = documentStore;
  47. Statistics = new Observable<DatabaseStatistics>();
  48. Status = new Observable<string>
  49. {
  50. Value = "Offline"
  51. };
  52. OnPropertyChanged(() => StatusImage);
  53. asyncDatabaseCommands = name.Equals(Constants.SystemDatabase, StringComparison.OrdinalIgnoreCase)
  54. ? documentStore.AsyncDatabaseCommands.ForSystemDatabase()
  55. : documentStore.AsyncDatabaseCommands.ForDatabase(name);
  56. DocumentChanges.Select(c => Unit.Default).Merge(IndexChanges.Select(c => Unit.Default))
  57. .SampleResponsive(TimeSpan.FromSeconds(2))
  58. .Subscribe(_ => RefreshStatistics());
  59. databaseChanges.ConnectionStatusChanged += (sender, args) =>
  60. {
  61. ApplicationModel.Current.Server.Value.SetConnected(((IDatabaseChanges)sender).Connected);
  62. UpdateStatus();
  63. };
  64. RefreshStatistics();
  65. }
  66. private void UpdateStatus()
  67. {
  68. Status.Value = ApplicationModel.Current.Server.Value.IsConnected.Value ? "Online" : "Offline";
  69. OnPropertyChanged(() => Status);
  70. OnPropertyChanged(() => StatusImage);
  71. }
  72. public void Update()
  73. {
  74. if (ApplicationModel.Current != null)
  75. ApplicationModel.Current.Server.Value.DocumentStore
  76. .AsyncDatabaseCommands
  77. .ForSystemDatabase()
  78. .GetAsync("Raven/Databases/" + Name)
  79. .ContinueOnSuccessInTheUIThread(doc =>
  80. {
  81. if (doc == null)
  82. return;
  83. DatabaseDocument = new Observable<DatabaseDocument>
  84. {
  85. Value = ApplicationModel.Current.Server.Value.DocumentStore.Conventions.CreateSerializer().Deserialize
  86. <DatabaseDocument>(new RavenJTokenReader(doc.DataAsJson))
  87. };
  88. OnPropertyChanged(() => HasReplication);
  89. });
  90. RefreshStatistics();
  91. }
  92. public bool HasReplication
  93. {
  94. get
  95. {
  96. return DatabaseDocument != null &&
  97. DatabaseDocument.Value.Settings != null &&
  98. DatabaseDocument.Value.Settings.ContainsKey("Raven/ActiveBundles") &&
  99. DatabaseDocument.Value.Settings["Raven/ActiveBundles"].Split(';').Contains("Replication", StringComparer.OrdinalIgnoreCase);
  100. }
  101. }
  102. public bool HasExpirationBundle
  103. {
  104. get
  105. {
  106. return DatabaseDocument != null &&
  107. DatabaseDocument.Value.Settings != null &&
  108. DatabaseDocument.Value.Settings.ContainsKey("Raven/ActiveBundles") &&
  109. DatabaseDocument.Value.Settings["Raven/ActiveBundles"].Split(';').Contains("DocumentExpiration", StringComparer.OrdinalIgnoreCase);
  110. }
  111. }
  112. public BindableCollection<TaskModel> Tasks { get; private set; }
  113. public IObservable<DocumentChangeNotification> DocumentChanges
  114. {
  115. get
  116. {
  117. if (documentChanges == null)
  118. {
  119. var changes = Changes();
  120. ApplicationModel.ChangesToDispose.Add(changes);
  121. documentChanges = changes
  122. .ForAllDocuments()
  123. .Publish(); // use a single underlying subscription
  124. var documentChangesSubscription =
  125. ((IConnectableObservable<DocumentChangeNotification>)documentChanges).Connect();
  126. disposable.Add(documentChangesSubscription);
  127. }
  128. return documentChanges;
  129. }
  130. }
  131. public IObservable<IndexChangeNotification> IndexChanges
  132. {
  133. get
  134. {
  135. if (indexChanges == null)
  136. {
  137. var changes = Changes();
  138. ApplicationModel.ChangesToDispose.Add(changes);
  139. indexChanges = changes
  140. .ForAllIndexes()
  141. .Publish(); // use a single underlying subscription
  142. var indexChangesSubscription = ((IConnectableObservable<IndexChangeNotification>)indexChanges).Connect();
  143. disposable.Add(indexChangesSubscription);
  144. }
  145. return indexChanges;
  146. }
  147. }
  148. public IDatabaseChanges Changes()
  149. {
  150. return databaseChanges ??
  151. (databaseChanges =
  152. name == Constants.SystemDatabase
  153. ? documentStore.Changes()
  154. : documentStore.Changes(name));
  155. }
  156. public IAsyncDatabaseCommands AsyncDatabaseCommands
  157. {
  158. get { return asyncDatabaseCommands; }
  159. }
  160. public string Name
  161. {
  162. get { return name; }
  163. }
  164. public Observable<DatabaseStatistics> Statistics { get; set; }
  165. public Observable<string> Status
  166. {
  167. get { return status; }
  168. set
  169. {
  170. status = value;
  171. OnPropertyChanged(() => Status);
  172. OnPropertyChanged(() => StatusImage);
  173. }
  174. }
  175. public Observable<BitmapImage> StatusImage
  176. {
  177. get
  178. {
  179. var url = new Uri("../Assets/Images/" + Status.Value + ".png", UriKind.Relative);
  180. return new Observable<BitmapImage> { Value = new BitmapImage(url) };
  181. }
  182. }
  183. private void RefreshStatistics()
  184. {
  185. asyncDatabaseCommands
  186. .GetStatisticsAsync()
  187. .ContinueOnSuccess(stats =>
  188. {
  189. Statistics.Value = stats;
  190. });
  191. }
  192. public void Dispose()
  193. {
  194. disposable.Dispose();
  195. using ((IDisposable)databaseChanges)
  196. {
  197. }
  198. }
  199. }
  200. }