Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'master' of github.com:fitzchak1/ravendb

  • Loading branch information...
commit 181a9c0cd87dc94675941021191e93b34520692e 2 parents 14b8a5a + 458dca7
Ayende Rahien authored July 07, 2011

Showing 47 changed files with 1,150 additions and 521 deletions. Show diff stats Hide diff stats

  1. 19  Raven.Studio/AppBootstrapper.cs
  2. 4  Raven.Studio/Behaviors/DocumentsContextMenu.cs
  3. 23  Raven.Studio/Commands/DeleteDocument.cs
  4. 6  Raven.Studio/Commands/EditIndex.cs
  5. 44  Raven.Studio/Commands/SaveDocument.cs
  6. 23  Raven.Studio/Common/String.cs
  7. 73  Raven.Studio/Features/Collections/CollectionsViewModel.cs
  8. 6  Raven.Studio/Features/Database/DatabaseExplorer.cs
  9. 8  Raven.Studio/Features/Database/SelectDatabaseViewModel.cs
  10. 6  Raven.Studio/Features/Database/Server.cs
  11. 502  Raven.Studio/Features/Database/SummaryViewModel.cs
  12. 22  Raven.Studio/Features/Documents/BrowseDocumentsViewModel.cs
  13. 14  Raven.Studio/Features/Documents/DocumentViewModel.cs
  14. 16  Raven.Studio/Features/Documents/EditDocumentViewModel.cs
  15. 61  Raven.Studio/Features/Indexes/BrowseIndexesViewModel.cs
  16. 19  Raven.Studio/Features/Indexes/EditIndexViewModel.cs
  17. 210  Raven.Studio/Features/Query/QueryViewModel.cs
  18. 25  Raven.Studio/Features/Statistics/ErrorsViewModel.cs
  19. 2  Raven.Studio/Features/Statistics/IndexesViewModel.cs
  20. 7  Raven.Studio/Features/Statistics/StatisticsViewModel.cs
  21. 16  Raven.Studio/Features/Tasks/ConsoleOutputTask.cs
  22. 7  Raven.Studio/Features/Tasks/ExportTask.cs
  23. 9  Raven.Studio/Features/Tasks/ImportTask.cs
  24. 30  Raven.Studio/Features/Tasks/TasksViewModel.cs
  25. 8  Raven.Studio/Framework/BindablePagedQuery.cs
  26. 3  Raven.Studio/Framework/ConventionalCatalog.cs
  27. 8  Raven.Studio/Framework/IRavenConductor.cs
  28. 45  Raven.Studio/Framework/RavenScreen.cs
  29. 9  Raven.Studio/Infrastructure/Navigation/INavigator.cs
  30. 18  Raven.Studio/Infrastructure/Navigation/INavigatorMetdata.cs
  31. 90  Raven.Studio/Infrastructure/Navigation/NavigationService.cs
  32. 8  Raven.Studio/Infrastructure/Navigation/NavigationState.cs
  33. 19  Raven.Studio/Infrastructure/Navigation/NavigatorExportAttribute.cs
  34. 46  Raven.Studio/Infrastructure/Navigation/Navigators/BaseNavigator.cs
  35. 31  Raven.Studio/Infrastructure/Navigation/Navigators/CollectionsNavigator.cs
  36. 38  Raven.Studio/Infrastructure/Navigation/Navigators/DatabaseExplorerNavigator.cs
  37. 23  Raven.Studio/Infrastructure/Navigation/Navigators/EditDocumentNavigator.cs
  38. 23  Raven.Studio/Infrastructure/Navigation/Navigators/ErrorsNavigator.cs
  39. 31  Raven.Studio/Infrastructure/Navigation/Navigators/IndexesNavigator.cs
  40. 23  Raven.Studio/Infrastructure/Navigation/Navigators/SelectDatabaseNavigator.cs
  41. 37  Raven.Studio/Infrastructure/Navigation/Navigators/TasksNavigator.cs
  42. 5  Raven.Studio/Plugins/Database/ExportDatabaseExplorerItemAttribute.cs
  43. 2  Raven.Studio/Plugins/IServer.cs
  44. 16  Raven.Studio/Raven.Studio.csproj
  45. 9  Raven.Studio/Shell/IShell.cs
  46. 1  Raven.Studio/Shell/NavigationViewModel.cs
  47. 26  Raven.Studio/Shell/ShellViewModel.cs
19  Raven.Studio/AppBootstrapper.cs
... ...
@@ -1,5 +1,8 @@
1 1
 using System.IO;
2 2
 using System.Security.Cryptography;
  3
+using Raven.Studio.Features.Documents;
  4
+using Raven.Studio.Infrastructure.Navigation;
  5
+using Raven.Studio.Plugins;
3 6
 
4 7
 namespace Raven.Studio
5 8
 {
@@ -26,6 +29,22 @@ static AppBootstrapper()
26 29
 			LogManager.GetLog = type => new DebugLogger(type);	
27 30
     	}
28 31
 
  32
+		protected override void OnStartup(object sender, StartupEventArgs e)
  33
+		{
  34
+			base.OnStartup(sender, e);
  35
+			var navigationService = container.GetExportedValue<NavigationService>();
  36
+			navigationService.Initialize();
  37
+
  38
+			MessageBinder.CustomConverters.Add(typeof(IList<string>), (providedValue, context) =>
  39
+			{
  40
+				var id = providedValue as string;
  41
+				if (id != null)
  42
+					return new List<string> {id};
  43
+
  44
+				return providedValue;
  45
+			});
  46
+		}
  47
+
29 48
 		protected override void Configure()
30 49
 		{
31 50
 			ConfigureConventions();
4  Raven.Studio/Behaviors/DocumentsContextMenu.cs
@@ -23,7 +23,7 @@ protected override void GenerateMenuItems()
23 23
 				if (SelectedItem.CollectionType != BuiltinCollectionName.Projection)
24 24
 				{
25 25
 					var deleteDocumentsMenuItem = new PopupMenuItem(null, string.Format(DocumentsResources.DocumentMenu_DeleteDocuments, SelectedItems.Count));
26  
-					deleteDocumentsMenuItem.Click += (s, ea) => IoC.Get<DeleteDocument>().Execute(SelectedItems);
  26
+					deleteDocumentsMenuItem.Click += (s, ea) => IoC.Get<DeleteDocument>().Execute(SelectedItems.Select(document => document.Id).ToList());
27 27
 					Menu.AddItem(deleteDocumentsMenuItem);
28 28
 				}
29 29
 			}
@@ -49,7 +49,7 @@ protected override void GenerateMenuItems()
49 49
 
50 50
 					var deleteDocumentMenuItem = new PopupMenuItem(null, DocumentsResources.DocumentMenu_DeleteDocument);
51 51
 					deleteDocumentMenuItem.Click +=
52  
-						(s, ea) => IoC.Get<DeleteDocument>().Execute(SelectedItems);
  52
+						(s, ea) => IoC.Get<DeleteDocument>().Execute(SelectedItems.Select(document => document.Id).ToList());
53 53
 					Menu.AddItem(deleteDocumentMenuItem);
54 54
 				}
55 55
 			}
23  Raven.Studio/Commands/DeleteDocument.cs
... ...
@@ -1,15 +1,11 @@
1 1
 using System.Collections.Generic;
2  
-using Raven.Studio.Features.Collections;
3 2
 
4 3
 namespace Raven.Studio.Commands
5 4
 {
6  
-    using System.Collections;
7  
-    using System.ComponentModel.Composition;
  5
+	using System.ComponentModel.Composition;
8 6
     using System.Linq;
9 7
     using Caliburn.Micro;
10  
-	using Features.Database;
11  
-    using Features.Documents;
12  
-    using Messages;
  8
+	using Messages;
13 9
 	using Plugins;
14 10
 	using Shell.MessageBox;
15 11
 
@@ -28,19 +24,18 @@ public DeleteDocument(IServer server, IEventAggregator events, ShowMessageBox sh
28 24
 			this.showMessageBox = showMessageBox;
29 25
 		}
30 26
 
31  
-		public bool CanExecute(IList<DocumentViewModel> documents)
  27
+		public bool CanExecute(IList<string> documentIds)
32 28
 		{
33  
-			if (documents == null || documents.Count == 0)
  29
+			if (documentIds == null || documentIds.Count == 0)
34 30
 				return false;
35 31
 
36  
-			var document = documents.First();
37  
-			return document != null && document.CollectionType != BuiltinCollectionName.Projection;
  32
+			return string.IsNullOrEmpty(documentIds.First()) == false;
38 33
 		}
39 34
 
40  
-		public void Execute(IList<DocumentViewModel> documents)
  35
+		public void Execute(IList<string> documentIds)
41 36
 		{
42  
-			string message = documents.Count > 1 ? string.Format("Are you sure you want to delete these {0} documents?", documents.Count) :
43  
-				string.Format("Are you sure that you want to do this document? ({0})", documents.First().Id);
  37
+			string message = documentIds.Count > 1 ? string.Format("Are you sure you want to delete these {0} documents?", documentIds.Count) :
  38
+				string.Format("Are you sure that you want to delete this document? ({0})", documentIds.First());
44 39
 
45 40
 			showMessageBox(
46 41
 				message,
@@ -49,7 +44,7 @@ public void Execute(IList<DocumentViewModel> documents)
49 44
 				box => {
50 45
 					if (box.WasSelected(MessageBoxOptions.Ok))
51 46
 					{
52  
-						documents.Apply(document => ExecuteDeletion(document.Id)); // Is this the most efficient way?
  47
+						documentIds.Apply(ExecuteDeletion); // Is this the most efficient way?
53 48
 					}
54 49
 				});
55 50
 		}
6  Raven.Studio/Commands/EditIndex.cs
@@ -2,7 +2,6 @@
2 2
 {
3 3
 	using System.ComponentModel.Composition;
4 4
 	using Caliburn.Micro;
5  
-	using Features.Database;
6 5
 	using Features.Indexes;
7 6
 	using Framework.Extensions;
8 7
 	using Messages;
@@ -26,8 +25,9 @@ public void Execute(string indexName)
26 25
 			server.OpenSession().Advanced.AsyncDatabaseCommands
27 26
 				.GetIndexAsync(indexName)
28 27
 				.ContinueOnSuccess(get =>
29  
-					{
30  
-						events.Publish(new DatabaseScreenRequested(() => new EditIndexViewModel(get.Result, server, events)));
  28
+				{
  29
+					events.Publish(
  30
+						new DatabaseScreenRequested(() => new EditIndexViewModel(get.Result)));
31 31
 						events.Publish(new WorkCompleted());
32 32
 					});
33 33
 		}
44  Raven.Studio/Commands/SaveDocument.cs
... ...
@@ -1,4 +1,5 @@
1 1
 using Raven.Abstractions.Extensions;
  2
+using Raven.Studio.Shell.MessageBox;
2 3
 
3 4
 namespace Raven.Studio.Commands
4 5
 {
@@ -16,18 +17,40 @@ public class SaveDocument
16 17
 	{
17 18
 		readonly IEventAggregator events;
18 19
 		readonly IServer server;
  20
+		private readonly ShowMessageBox showMessageBox;
19 21
 
20 22
 		[ImportingConstructor]
21  
-		public SaveDocument(IEventAggregator events, IServer server)
  23
+		public SaveDocument(IEventAggregator events, IServer server, ShowMessageBox showMessageBox)
22 24
 		{
23 25
 			this.events = events;
24 26
 			this.server = server;
  27
+			this.showMessageBox = showMessageBox;
25 28
 		}
26 29
 
27 30
 		public void Execute(EditDocumentViewModel document)
28 31
 		{
29 32
 			if(!ValidateJson(document.JsonData) || !ValidateJson(document.JsonMetadata)) return;
30 33
 
  34
+			if (document.Id.StartsWith("Raven/"))
  35
+			{
  36
+				showMessageBox(
  37
+					"Are you sure that you want to edit a system document?",
  38
+					"Confirm Edit",
  39
+					MessageBoxOptions.OkCancel,
  40
+					box =>
  41
+						{
  42
+							if (box.WasSelected(MessageBoxOptions.Ok))
  43
+							{
  44
+								Delete(document);
  45
+							}
  46
+						});
  47
+				return;
  48
+			}
  49
+			Delete(document);
  50
+		}
  51
+
  52
+		private void Delete(EditDocumentViewModel document)
  53
+		{
31 54
 			document.PrepareForSave();
32 55
 
33 56
 			var jdoc = document.JsonDocument;
@@ -35,17 +58,16 @@ public void Execute(EditDocumentViewModel document)
35 58
 			server.OpenSession().Advanced.AsyncDatabaseCommands
36 59
 				.PutAsync(document.Id, jdoc.Etag, jdoc.DataAsJson, jdoc.Metadata)
37 60
 				.ContinueOnSuccess(put =>
38  
-				                   	{
39  
-										var inner = document.JsonDocument;
40  
-										inner.Key = put.Result.Key;
41  
-										inner.Metadata = inner.Metadata.FilterHeaders(isServerDocument: false);
42  
-										inner.Etag = put.Result.ETag;
43  
-										inner.LastModified = DateTime.Now;
44  
-				                        document.UpdateDocumentFromJsonDocument();
  61
+				{
  62
+					var inner = document.JsonDocument;
  63
+					inner.Key = put.Result.Key;
  64
+					inner.Metadata = inner.Metadata.FilterHeaders(isServerDocument: false);
  65
+					inner.Etag = put.Result.ETag;
  66
+					inner.LastModified = DateTime.Now;
  67
+					document.UpdateDocumentFromJsonDocument();
45 68
 
46  
-                                        events.Publish(new DocumentUpdated(document));
47  
-				                   	});
48  
-			
  69
+					events.Publish(new DocumentUpdated(document));
  70
+				});
49 71
 		}
50 72
 
51 73
 		bool ValidateJson(string json)
23  Raven.Studio/Common/String.cs
... ...
@@ -0,0 +1,23 @@
  1
+// -----------------------------------------------------------------------
  2
+//  <copyright file="CanGetStats.cs" company="Hibernating Rhinos LTD">
  3
+//      Copyright (c) Hibernating Rhinos LTD. All rights reserved.
  4
+//  </copyright>
  5
+// -----------------------------------------------------------------------
  6
+
  7
+namespace Raven.Studio.Common
  8
+{
  9
+	public static class StringExtensions
  10
+	{
  11
+		public static string FirstWord(this string text)
  12
+		{
  13
+			if (text == null)
  14
+				return null;
  15
+
  16
+			var index = text.IndexOf(' ');
  17
+			if (index == -1)
  18
+				return text;
  19
+			
  20
+			return text.Substring(0, index);
  21
+		}
  22
+	}
  23
+}
73  Raven.Studio/Features/Collections/CollectionsViewModel.cs
... ...
@@ -1,4 +1,5 @@
1 1
 using Raven.Client.Connection;
  2
+using Raven.Studio.Infrastructure.Navigation;
2 3
 
3 4
 namespace Raven.Studio.Features.Collections
4 5
 {
@@ -16,25 +17,21 @@ namespace Raven.Studio.Features.Collections
16 17
 	using Plugins;
17 18
 	using Plugins.Database;
18 19
 
19  
-	[Export(typeof(CollectionsViewModel))]
20  
-	[ExportDatabaseExplorerItem("Collections", Index = 20)]
  20
+	[Export]
  21
+	[ExportDatabaseExplorerItem(DisplayName = "Collections", Index = 20)]
21 22
 	public class CollectionsViewModel : RavenScreen,
22 23
 		IHandle<DocumentDeleted>
23 24
 	{
24  
-		readonly IServer server;
25 25
 		CollectionViewModel activeCollection;
26 26
 
27 27
 		[ImportingConstructor]
28  
-		public CollectionsViewModel(IServer server, IEventAggregator events)
29  
-			: base(events)
  28
+		public CollectionsViewModel()
30 29
 		{
31 30
 			DisplayName = "Collections";
32 31
 
33  
-			events.Subscribe(this);
  32
+			Events.Subscribe(this);
34 33
 
35  
-			this.server = server;
36  
-
37  
-			server.CurrentDatabaseChanged += delegate
  34
+			Server.CurrentDatabaseChanged += delegate
38 35
 			{
39 36
 				Initialize();
40 37
 			};
@@ -63,6 +60,8 @@ public BindablePagedQuery<DocumentViewModel> ActiveCollectionDocuments
63 60
 		}
64 61
 
65 62
 		string status;
  63
+		private System.Action executeAfterCollectionsFetched;
  64
+
66 65
 		public string Status
67 66
 		{
68 67
 			get { return status; }
@@ -99,19 +98,34 @@ public bool HasCollections
99 98
 
100 99
 		void GetDocumentsForActiveCollection()
101 100
 		{
  101
+			TrackCurrentCollection();
  102
+
102 103
 			ActiveCollectionDocuments.ClearResults();
103  
-			
  104
+
104 105
 			if (ActiveCollection == null) return;
105 106
 
106 107
 			ActiveCollectionDocuments.GetTotalResults = () => ActiveCollection.Count;
107 108
 			ActiveCollectionDocuments.LoadPage();
108 109
 		}
109 110
 
  111
+		private void TrackCurrentCollection()
  112
+		{
  113
+			if (ActiveCollection == null)
  114
+				return;
  115
+
  116
+			Execute.OnUIThread(() =>
  117
+							   NavigationService.Track(new NavigationState
  118
+														{
  119
+															Url = string.Format("collections/{0}", ActiveCollection.Name),
  120
+															Title = string.Format("Collections: {0}", ActiveCollection.Name)
  121
+														}));
  122
+		}
  123
+
110 124
 		Task<DocumentViewModel[]> GetDocumentsForActiveCollectionQuery(int start, int pageSize)
111 125
 		{
112 126
 			WorkStarted("retrieving documents for collection.");
113 127
 
114  
-			using (var session = server.OpenSession())
  128
+			using (var session = Server.OpenSession())
115 129
 			{
116 130
 				var query = new IndexQuery { Start = start, PageSize = pageSize, Query = "Tag:" + ActiveCollection.Name };
117 131
 				return session.Advanced.AsyncDatabaseCommands
@@ -129,11 +143,28 @@ Task<DocumentViewModel[]> GetDocumentsForActiveCollectionQuery(int start, int pa
129 143
 			}
130 144
 		}
131 145
 
  146
+		public void SelectCollectionByName(string name)
  147
+		{
  148
+			if (HasCollections)
  149
+			{
  150
+				var collection = Collections
  151
+					.Where(item => item.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
  152
+					.FirstOrDefault();
  153
+
  154
+				if (collection == null)
  155
+					return;
  156
+
  157
+				ActiveCollection = collection;
  158
+				return;
  159
+			}
  160
+			executeAfterCollectionsFetched = () => SelectCollectionByName(name);
  161
+		}
  162
+
132 163
 		protected override void OnActivate()
133 164
 		{
134 165
 			WorkStarted("fetching collections");
135 166
 
136  
-			using (var session = server.OpenSession())
  167
+			using (var session = Server.OpenSession())
137 168
 			{
138 169
 				session.Advanced.AsyncDatabaseCommands
139 170
 					.GetCollectionsAsync(0, 25)
@@ -143,7 +174,7 @@ protected override void OnActivate()
143 174
 						WorkCompleted("fetching collections");
144 175
 
145 176
 						Collections = new BindableCollection<CollectionViewModel>(
146  
-							x.Result.Select(item => new CollectionViewModel {Name = item.Name, Count = item.Count}));
  177
+							x.Result.Select(item => new CollectionViewModel { Name = item.Name, Count = item.Count }));
147 178
 
148 179
 						NotifyOfPropertyChange(() => LargestCollectionCount);
149 180
 						NotifyOfPropertyChange(() => Collections);
@@ -152,21 +183,27 @@ protected override void OnActivate()
152 183
 						if (ActiveCollection != null)
153 184
 						{
154 185
 							activeCollection = Collections
155  
-								.Where(collection => collection.Name == activeCollection.Name)
156  
-								.FirstOrDefault(); 
157  
-							NotifyOfPropertyChange(() => ActiveCollection); 
  186
+								.Where(collection => collection.Name == ActiveCollection.Name)
  187
+								.FirstOrDefault();
  188
+							NotifyOfPropertyChange(() => ActiveCollection);
  189
+							TrackCurrentCollection();
158 190
 						}
159 191
 						else // select the first one if we weren't asked for one
160 192
 						{
161 193
 							ActiveCollection = Collections.FirstOrDefault();
162 194
 						}
  195
+						if (executeAfterCollectionsFetched != null)
  196
+						{
  197
+							executeAfterCollectionsFetched();
  198
+							executeAfterCollectionsFetched = null;
  199
+						}
163 200
 
164 201
 						Status = Collections.Any() ? string.Empty : "The database contains no collections.";
165 202
 					},
166 203
 					faulted =>
167 204
 					{
168 205
 						WorkCompleted("fetching collections");
169  
-						var error = "Unable to retrieve collections from server.";
  206
+						const string error = "Unable to retrieve collections from server."; ;
170 207
 						Status = error;
171 208
 						NotifyError(error);
172 209
 					});
@@ -176,7 +213,7 @@ protected override void OnActivate()
176 213
 		public void EditTemplate()
177 214
 		{
178 215
 			var vm = IoC.Get<EditCollectionTemplateViewModel>();
179  
-			vm.Collection = new Collection {Name = ActiveCollection.Name, Count = ActiveCollection.Count};
  216
+			vm.Collection = new Collection { Name = ActiveCollection.Name, Count = ActiveCollection.Count };
180 217
 			Events.Publish(new DatabaseScreenRequested(() => vm));
181 218
 		}
182 219
 
6  Raven.Studio/Features/Database/DatabaseExplorer.cs
... ...
@@ -1,3 +1,5 @@
  1
+using System.Windows;
  2
+
1 3
 namespace Raven.Studio.Features.Database
2 4
 {
3 5
 	using System;
@@ -88,7 +90,9 @@ void IPartImportsSatisfiedNotification.OnImportsSatisfied()
88 90
 				.OrderBy(x => x.Metadata.Index)
89 91
 				.Select(x => x.Metadata.DisplayName)
90 92
 				.ToList();
91  
-			
  93
+
  94
+			if (string.IsNullOrEmpty(Application.Current.Host.NavigationState) == false) 
  95
+				return;
92 96
 			ShowFirstScreen();
93 97
 		}
94 98
 
8  Raven.Studio/Features/Database/SelectDatabaseViewModel.cs
... ...
@@ -1,3 +1,5 @@
  1
+using Raven.Studio.Infrastructure.Navigation;
  2
+
1 3
 namespace Raven.Studio.Features.Database
2 4
 {
3 5
     using System.ComponentModel.Composition;
@@ -14,16 +16,12 @@ public class SelectDatabaseViewModel : RavenScreen
14 16
         private Visibility showCreateDatabaseForm;
15 17
 
16 18
         [ImportingConstructor]
17  
-        public SelectDatabaseViewModel(IServer server, IEventAggregator events)
18  
-            : base(events)
  19
+		public SelectDatabaseViewModel()
19 20
         {
20 21
             DisplayName = "Home";
21  
-            Server = server;
22 22
             ShowCreateDatabaseForm = Visibility.Collapsed;
23 23
         }
24 24
 
25  
-        public IServer Server { get; private set; }
26  
-
27 25
         public Visibility ShowCreateDatabaseForm
28 26
         {
29 27
             get { return showCreateDatabaseForm; }
6  Raven.Studio/Features/Database/Server.cs
@@ -31,7 +31,7 @@ namespace Raven.Studio.Features.Database
31 31
 	public class Server : PropertyChangedBase, IServer,
32 32
 		IHandle<StatisticsUpdateRequested>
33 33
 	{
34  
-		const string DefaultDatabaseName = "Default Database";
  34
+		public const string DefaultDatabaseName = "Default Database";
35 35
 		readonly IEventAggregator events;
36 36
 
37 37
 		readonly Dictionary<string, DatabaseStatistics> snapshots = new Dictionary<string, DatabaseStatistics>();
@@ -118,6 +118,8 @@ public void Connect(Uri serverAddress, Action callback)
118 118
 
119 119
 								if (callback != null) callback();
120 120
 							});
  121
+
  122
+							SetBuildNumber();
121 123
 						},
122 124
 						faulted =>
123 125
 						{
@@ -213,8 +215,6 @@ public void OpenDatabase(string name, Action callback)
213 215
 			using (var session = OpenSession())
214 216
 				session.Advanced.AsyncDatabaseCommands.EnsureSilverlightStartUpAsync();
215 217
 
216  
-			SetBuildNumber();
217  
-
218 218
 			callback();
219 219
 		}
220 220
 
502  Raven.Studio/Features/Database/SummaryViewModel.cs
@@ -2,266 +2,260 @@
2 2
 using Raven.Abstractions.Extensions;
3 3
 using Raven.Abstractions.Indexing;
4 4
 using Raven.Json.Linq;
  5
+using Raven.Studio.Infrastructure.Navigation;
5 6
 
6 7
 namespace Raven.Studio.Features.Database
7 8
 {
8  
-    using System;
9  
-    using System.Collections.Generic;
10  
-    using System.ComponentModel.Composition;
11  
-    using System.IO;
12  
-    using System.Linq;
13  
-    using System.Threading.Tasks;
14  
-    using Abstractions.Data;
15  
-    using Caliburn.Micro;
16  
-    using Client;
17  
-    using Collections;
18  
-    using Documents;
19  
-    using Framework;
20  
-    using Framework.Extensions;
21  
-    using Messages;
22  
-    using Newtonsoft.Json;
23  
-    using Plugins;
24  
-    using Plugins.Database;
25  
-
26  
-    [ExportDatabaseExplorerItem("Summary", Index = 10)]
27  
-    public class SummaryViewModel : RavenScreen,
28  
-                                    IHandle<DocumentDeleted>,
29  
-                                    IHandle<StatisticsUpdated>
30  
-    {
31  
-        readonly IEventAggregator events;
32  
-        readonly IServer server;
33  
-
34  
-        [ImportingConstructor]
35  
-        public SummaryViewModel(IServer server, IEventAggregator events)
36  
-            : base(events)
37  
-        {
38  
-            this.server = server;
39  
-            this.events = events;
40  
-            events.Subscribe(this);
41  
-
42  
-            DisplayName = "Summary";
43  
-
44  
-            server.CurrentDatabaseChanged += delegate
45  
-            {
46  
-                Collections = new BindableCollection<Collection>();
47  
-                RecentDocuments = new BindableCollection<DocumentViewModel>();
48  
-                RetrieveSummary();
49  
-
50  
-                CollectionsStatus = "Retrieving collections.";
51  
-                RecentDocumentsStatus = "Retrieving recent documents.";
52  
-                ShowCreateSampleData = false;
53  
-                IsGeneratingSampleData = false;
54  
-
55  
-                NotifyOfPropertyChange(string.Empty);
56  
-            };
57  
-        }
58  
-
59  
-        public string DatabaseName { get { return server.CurrentDatabase; } }
60  
-
61  
-        public IServer Server { get { return server; } }
62  
-
63  
-        public BindableCollection<DocumentViewModel> RecentDocuments { get; private set; }
64  
-
65  
-        public BindableCollection<Collection> Collections { get; private set; }
66  
-
67  
-        string collectionsStatus;
68  
-        public string CollectionsStatus
69  
-        {
70  
-            get { return collectionsStatus; }
71  
-            set
72  
-            {
73  
-                collectionsStatus = value;
74  
-                NotifyOfPropertyChange(() => CollectionsStatus);
75  
-            }
76  
-        }
77  
-
78  
-        string recentDocumentsStatus;
79  
-        public string RecentDocumentsStatus
80  
-        {
81  
-            get { return recentDocumentsStatus; }
82  
-            set
83  
-            {
84  
-                recentDocumentsStatus = value;
85  
-                NotifyOfPropertyChange(() => RecentDocumentsStatus);
86  
-            }
87  
-        }
88  
-
89  
-        public long LargestCollectionCount
90  
-        {
91  
-            get
92  
-            {
93  
-                return (Collections == null || !Collections.Any())
94  
-                        ? 0
95  
-                        : Collections.Max(x => x.Count);
96  
-            }
97  
-        }
98  
-
99  
-        bool showCreateSampleData;
100  
-
101  
-        public bool ShowCreateSampleData
102  
-        {
103  
-            get { return showCreateSampleData; }
104  
-            set { showCreateSampleData = value; NotifyOfPropertyChange(() => ShowCreateSampleData); }
105  
-        }
106  
-
107  
-        public void BeginCreateSampleData()
108  
-        {
109  
-            var tasks = (IEnumerable<Task>)CreateSampleData().GetEnumerator();
110  
-            tasks.ExecuteInSequence(null);
111  
-        }
112  
-
113  
-        IEnumerable<Task> CreateSampleData()
114  
-        {
115  
-            // this code assumes a small enough dataset, and doesn't do any sort
116  
-            // of paging or batching whatsoever.
117  
-
118  
-            ShowCreateSampleData = false;
119  
-            IsGeneratingSampleData = true;
120  
-
121  
-            WorkStarted("creating sample data");
122  
-            WorkStarted("creating sample indexes");
123  
-            using (var documentSession = Server.OpenSession())
124  
-            using (var sampleData = typeof(SummaryViewModel).Assembly.GetManifestResourceStream("Raven.Studio.SampleData.MvcMusicStore_Dump.json"))
125  
-            using (var streamReader = new StreamReader(sampleData))
126  
-            {
127  
-            	var putTask = documentSession.Advanced.AsyncDatabaseCommands
128  
-                    .DeleteDocumentAsync("forceAuth_" + Guid.NewGuid());
129  
-
130  
-                yield return putTask;
131  
-
132  
-                if (putTask.Exception != null) yield break;
  9
+	using System;
  10
+	using System.Collections.Generic;
  11
+	using System.ComponentModel.Composition;
  12
+	using System.IO;
  13
+	using System.Linq;
  14
+	using System.Threading.Tasks;
  15
+	using Abstractions.Data;
  16
+	using Caliburn.Micro;
  17
+	using Client;
  18
+	using Collections;
  19
+	using Documents;
  20
+	using Framework;
  21
+	using Framework.Extensions;
  22
+	using Messages;
  23
+	using Newtonsoft.Json;
  24
+	using Plugins;
  25
+	using Plugins.Database;
  26
+
  27
+	[Export]
  28
+	[ExportDatabaseExplorerItem(DisplayName = "Summary", Index = 10)]
  29
+	public class SummaryViewModel : RavenScreen,
  30
+									IHandle<DocumentDeleted>,
  31
+									IHandle<StatisticsUpdated>
  32
+	{
  33
+		[ImportingConstructor]
  34
+		public SummaryViewModel()
  35
+		{
  36
+			Events.Subscribe(this);
  37
+
  38
+			DisplayName = "Summary";
  39
+
  40
+			Server.CurrentDatabaseChanged += delegate
  41
+			{
  42
+				Collections = new BindableCollection<Collection>();
  43
+				RecentDocuments = new BindableCollection<DocumentViewModel>();
  44
+				RetrieveSummary();
  45
+
  46
+				CollectionsStatus = "Retrieving collections.";
  47
+				RecentDocumentsStatus = "Retrieving recent documents.";
  48
+				ShowCreateSampleData = false;
  49
+				IsGeneratingSampleData = false;
  50
+
  51
+				NotifyOfPropertyChange(string.Empty);
  52
+			};
  53
+		}
  54
+
  55
+		public string DatabaseName { get { return Server.CurrentDatabase; } }
  56
+
  57
+		public BindableCollection<DocumentViewModel> RecentDocuments { get; private set; }
  58
+
  59
+		public BindableCollection<Collection> Collections { get; private set; }
  60
+
  61
+		string collectionsStatus;
  62
+		public string CollectionsStatus
  63
+		{
  64
+			get { return collectionsStatus; }
  65
+			set
  66
+			{
  67
+				collectionsStatus = value;
  68
+				NotifyOfPropertyChange(() => CollectionsStatus);
  69
+			}
  70
+		}
  71
+
  72
+		string recentDocumentsStatus;
  73
+		public string RecentDocumentsStatus
  74
+		{
  75
+			get { return recentDocumentsStatus; }
  76
+			set
  77
+			{
  78
+				recentDocumentsStatus = value;
  79
+				NotifyOfPropertyChange(() => RecentDocumentsStatus);
  80
+			}
  81
+		}
  82
+
  83
+		public long LargestCollectionCount
  84
+		{
  85
+			get
  86
+			{
  87
+				return (Collections == null || !Collections.Any())
  88
+						? 0
  89
+						: Collections.Max(x => x.Count);
  90
+			}
  91
+		}
  92
+
  93
+		bool showCreateSampleData;
  94
+
  95
+		public bool ShowCreateSampleData
  96
+		{
  97
+			get { return showCreateSampleData; }
  98
+			set { showCreateSampleData = value; NotifyOfPropertyChange(() => ShowCreateSampleData); }
  99
+		}
  100
+
  101
+		public void BeginCreateSampleData()
  102
+		{
  103
+			var tasks = (IEnumerable<Task>)CreateSampleData().GetEnumerator();
  104
+			tasks.ExecuteInSequence(null);
  105
+		}
  106
+
  107
+		IEnumerable<Task> CreateSampleData()
  108
+		{
  109
+			// this code assumes a small enough dataset, and doesn't do any sort
  110
+			// of paging or batching whatsoever.
  111
+
  112
+			ShowCreateSampleData = false;
  113
+			IsGeneratingSampleData = true;
  114
+
  115
+			WorkStarted("creating sample data");
  116
+			WorkStarted("creating sample indexes");
  117
+			using (var documentSession = Server.OpenSession())
  118
+			using (var sampleData = typeof(SummaryViewModel).Assembly.GetManifestResourceStream("Raven.Studio.SampleData.MvcMusicStore_Dump.json"))
  119
+			using (var streamReader = new StreamReader(sampleData))
  120
+			{
  121
+				var putTask = documentSession.Advanced.AsyncDatabaseCommands
  122
+					.DeleteDocumentAsync("forceAuth_" + Guid.NewGuid());
  123
+
  124
+				yield return putTask;
  125
+
  126
+				if (putTask.Exception != null) yield break;
133 127
 
134 128
 				var musicStoreData = (RavenJObject)RavenJToken.ReadFrom(new JsonTextReader(streamReader));
135  
-                foreach (var index in musicStoreData.Value<RavenJArray>("Indexes"))
136  
-                {
137  
-                    var indexName = index.Value<string>("name");
138  
-                    var putDoc = documentSession.Advanced.AsyncDatabaseCommands
139  
-                        .PutIndexAsync(indexName,
140  
-                                        index.Value<RavenJObject>("definition").JsonDeserialization<IndexDefinition>(),
141  
-                                        true);
142  
-                    yield return putDoc;
143  
-                }
144  
-
145  
-                WorkCompleted("creating sample indexes");
146  
-
147  
-                var batch = documentSession.Advanced.AsyncDatabaseCommands
148  
-                    .BatchAsync(
  129
+				foreach (var index in musicStoreData.Value<RavenJArray>("Indexes"))
  130
+				{
  131
+					var indexName = index.Value<string>("name");
  132
+					var putDoc = documentSession.Advanced.AsyncDatabaseCommands
  133
+						.PutIndexAsync(indexName,
  134
+										index.Value<RavenJObject>("definition").JsonDeserialization<IndexDefinition>(),
  135
+										true);
  136
+					yield return putDoc;
  137
+				}
  138
+
  139
+				WorkCompleted("creating sample indexes");
  140
+
  141
+				var batch = documentSession.Advanced.AsyncDatabaseCommands
  142
+					.BatchAsync(
149 143
 						musicStoreData.Value<RavenJArray>("Docs").OfType<RavenJObject>().Select(
150  
-                        doc =>
151  
-                        {
  144
+						doc =>
  145
+						{
152 146
 							var metadata = doc.Value<RavenJObject>("@metadata");
153  
-                            doc.Remove("@metadata");
154  
-                            return new PutCommandData
155  
-                                        {
156  
-                                            Document = doc,
157  
-                                            Metadata = metadata,
158  
-                                            Key = metadata.Value<string>("@id"),
159  
-                                        };
160  
-                        }).ToArray()
161  
-                    );
162  
-                yield return batch;
163  
-
164  
-                WorkCompleted("creating sample data");
165  
-                IsGeneratingSampleData = false;
166  
-                RecentDocumentsStatus = "Retrieving sample documents.";
167  
-                RetrieveSummary();
168  
-            }
169  
-        }
170  
-
171  
-        bool isGeneratingSampleData;
172  
-        public bool IsGeneratingSampleData
173  
-        {
174  
-            get { return isGeneratingSampleData; }
175  
-            set { isGeneratingSampleData = value; NotifyOfPropertyChange(() => IsGeneratingSampleData); }
176  
-        }
177  
-
178  
-        public void NavigateToCollection(Collection collection)
179  
-        {
180  
-            events.Publish(new DatabaseScreenRequested(() =>
181  
-                                                        {
182  
-                                                            var vm = IoC.Get<CollectionsViewModel>();
183  
-                                                            vm.ActiveCollection = new CollectionViewModel{Name = collection.Name, Count = collection.Count};
184  
-                                                            return vm;
185  
-                                                        }));
186  
-        }
187  
-
188  
-        protected override void OnActivate()
189  
-        {
190  
-            RetrieveSummary();
191  
-        }
192  
-
193  
-        void RetrieveSummary()
194  
-        {
195  
-            using (var session = server.OpenSession())
196  
-            {
197  
-                ExecuteCollectionQueryWithRetry(session, 5);
198  
-
199  
-                WorkStarted("fetching recent documents");
200  
-                session.Advanced.AsyncDatabaseCommands
201  
-                    .GetDocumentsAsync(0, 12)
202  
-                    .ContinueWith(
203  
-                        x =>
204  
-                        {
205  
-                            WorkCompleted("fetching recent documents");
206  
-                            RecentDocuments = new BindableCollection<DocumentViewModel>(x.Result.Select(jdoc => new DocumentViewModel(jdoc)));
207  
-                            NotifyOfPropertyChange(() => RecentDocuments);
208  
-
209  
-                            ShowCreateSampleData = !RecentDocuments.Any();
210  
-
211  
-                            RecentDocumentsStatus = RecentDocuments.Any() ? string.Empty : "The database contains no documents.";
212  
-
213  
-                        },
214  
-                        faulted =>
215  
-                        {
216  
-                            WorkCompleted("fetching recent documents");
217  
-                            NotifyError("Unable to retrieve recent documents from server.");
218  
-                        });
219  
-            }
220  
-        }
221  
-
222  
-        void ExecuteCollectionQueryWithRetry(IAsyncDocumentSession session, int retry)
223  
-        {
224  
-            WorkStarted("fetching collections");
225  
-            session.Advanced.AsyncDatabaseCommands
226  
-                .GetCollectionsAsync(0, 25)
227  
-                .ContinueWith(task =>
228  
-                    {
229  
-                        if (task.Exception != null && retry > 0)
230  
-                        {
231  
-                            WorkCompleted("fetching collections");
232  
-                            TaskEx.Delay(50)
233  
-                                .ContinueWith(_ => ExecuteCollectionQueryWithRetry(session, retry - 1));
234  
-                            return;
235  
-                        }
236  
-
237  
-                        task.ContinueWith(
238  
-                            x =>
239  
-                            {
240  
-                                WorkCompleted("fetching collections");
241  
-                                Collections = new BindableCollection<Collection>(x.Result);
242  
-                                NotifyOfPropertyChange(() => LargestCollectionCount);
243  
-                                NotifyOfPropertyChange(() => Collections);
244  
-                                CollectionsStatus = Collections.Any() ? string.Empty : "The database contains no collections.";
245  
-                            },
246  
-                            faulted =>
247  
-                            {
248  
-                                WorkCompleted("fetching collections");
249  
-                                const string error = "Unable to retrieve collections from server.";
250  
-                                NotifyError(error);
251  
-                                CollectionsStatus = error;
252  
-                                NotifyOfPropertyChange(() => LargestCollectionCount);
253  
-                                NotifyOfPropertyChange(() => Collections);
254  
-
255  
-                            });
256  
-                    });
257  
-        }
258  
-
259  
-    	void IHandle<StatisticsUpdated>.Handle(StatisticsUpdated message)
260  
-        {
261  
-            if (!message.HasDocumentCountChanged) return;
262  
-
263  
-            RetrieveSummary();
264  
-        }
  147
+							doc.Remove("@metadata");
  148
+							return new PutCommandData
  149
+										{
  150
+											Document = doc,
  151
+											Metadata = metadata,
  152
+											Key = metadata.Value<string>("@id"),
  153
+										};
  154
+						}).ToArray()
  155
+					);
  156
+				yield return batch;
  157
+
  158
+				WorkCompleted("creating sample data");
  159
+				IsGeneratingSampleData = false;
  160
+				RecentDocumentsStatus = "Retrieving sample documents.";
  161
+				RetrieveSummary();
  162
+			}
  163
+		}
  164
+
  165
+		bool isGeneratingSampleData;
  166
+		public bool IsGeneratingSampleData
  167
+		{
  168
+			get { return isGeneratingSampleData; }
  169
+			set { isGeneratingSampleData = value; NotifyOfPropertyChange(() => IsGeneratingSampleData); }
  170
+		}
  171
+
  172
+		public void NavigateToCollection(Collection collection)
  173
+		{
  174
+			Events.Publish(new DatabaseScreenRequested(() =>
  175
+														{
  176
+															var vm = IoC.Get<CollectionsViewModel>();
  177
+															vm.ActiveCollection = new CollectionViewModel { Name = collection.Name, Count = collection.Count };
  178
+															return vm;
  179
+														}));
  180
+		}
  181
+
  182
+		protected override void OnActivate()
  183
+		{
  184
+			RetrieveSummary();
  185
+		}
  186
+
  187
+		void RetrieveSummary()
  188
+		{
  189
+			using (var session = Server.OpenSession())
  190
+			{
  191
+				ExecuteCollectionQueryWithRetry(session, 5);
  192
+
  193
+				WorkStarted("fetching recent documents");
  194
+				session.Advanced.AsyncDatabaseCommands
  195
+					.GetDocumentsAsync(0, 12)
  196
+					.ContinueWith(
  197
+						x =>
  198
+						{
  199
+							WorkCompleted("fetching recent documents");
  200
+							RecentDocuments = new BindableCollection<DocumentViewModel>(x.Result.Select(jdoc => new DocumentViewModel(jdoc)));
  201
+							NotifyOfPropertyChange(() => RecentDocuments);
  202
+
  203
+							ShowCreateSampleData = !RecentDocuments.Any();
  204
+
  205
+							RecentDocumentsStatus = RecentDocuments.Any() ? string.Empty : "The database contains no documents.";
  206
+
  207
+						},
  208
+						faulted =>
  209
+						{
  210
+							WorkCompleted("fetching recent documents");
  211
+							NotifyError("Unable to retrieve recent documents from server.");
  212
+						});
  213
+			}
  214
+		}
  215
+
  216
+		void ExecuteCollectionQueryWithRetry(IAsyncDocumentSession session, int retry)
  217
+		{
  218
+			WorkStarted("fetching collections");
  219
+			session.Advanced.AsyncDatabaseCommands
  220
+				.GetCollectionsAsync(0, 25)
  221
+				.ContinueWith(task =>
  222
+					{
  223
+						if (task.Exception != null && retry > 0)
  224
+						{
  225
+							WorkCompleted("fetching collections");
  226
+							TaskEx.Delay(50)
  227
+								.ContinueWith(_ => ExecuteCollectionQueryWithRetry(session, retry - 1));
  228
+							return;
  229
+						}
  230
+
  231
+						task.ContinueWith(
  232
+							x =>
  233
+							{
  234
+								WorkCompleted("fetching collections");
  235
+								Collections = new BindableCollection<Collection>(x.Result);
  236
+								NotifyOfPropertyChange(() => LargestCollectionCount);
  237
+								NotifyOfPropertyChange(() => Collections);
  238
+								CollectionsStatus = Collections.Any() ? string.Empty : "The database contains no collections.";
  239
+							},
  240
+							faulted =>
  241
+							{
  242
+								WorkCompleted("fetching collections");
  243
+								const string error = "Unable to retrieve collections from server.";
  244
+								NotifyError(error);
  245
+								CollectionsStatus = error;
  246
+								NotifyOfPropertyChange(() => LargestCollectionCount);
  247
+								NotifyOfPropertyChange(() => Collections);
  248
+
  249
+							});
  250
+					});
  251
+		}
  252
+
  253
+		void IHandle<StatisticsUpdated>.Handle(StatisticsUpdated message)
  254
+		{
  255
+			if (!message.HasDocumentCountChanged) return;
  256
+
  257
+			RetrieveSummary();
  258
+		}
265 259
 
266 260
 		void IHandle<DocumentDeleted>.Handle(DocumentDeleted message)
267 261
 		{
@@ -275,5 +269,5 @@ void IHandle<DocumentDeleted>.Handle(DocumentDeleted message)
275 269
 			//    .Where(x => x.Name == message.Document.CollectionType)
276 270
 			//    .Apply(x => x.Count--);
277 271
 		}
278  
-    }
  272
+	}
279 273
 }
22  Raven.Studio/Features/Documents/BrowseDocumentsViewModel.cs
... ...
@@ -1,4 +1,5 @@
1 1
 using Raven.Abstractions.Data;
  2
+using Raven.Studio.Infrastructure.Navigation;
2 3
 
3 4
 namespace Raven.Studio.Features.Documents
4 5
 {
@@ -11,25 +12,20 @@ namespace Raven.Studio.Features.Documents
11 12
 	using Plugins;
12 13
 	using Plugins.Database;
13 14
 
14  
-    [Export]
15  
-	[ExportDatabaseExplorerItem("Documents", Index = 40)]
  15
+	[Export]
  16
+	[ExportDatabaseExplorerItem(DisplayName = "Documents", Index = 40)]
16 17
 	public class BrowseDocumentsViewModel : RavenScreen,
17 18
 		IHandle<DocumentDeleted>
18 19
 	{
19  
-		readonly IEventAggregator events;
20  
-		readonly IServer server;
21 20
 		string status;
22 21
 
23 22
 		[ImportingConstructor]
24  
-		public BrowseDocumentsViewModel(IServer server, IEventAggregator events)
25  
-			: base(events)
  23
+		public BrowseDocumentsViewModel()
26 24
 		{
27 25
 			DisplayName = "Documents";
28  
-			this.server = server;
29  
-			this.events = events;
30  
-			events.Subscribe(this);
  26
+			Events.Subscribe(this);
31 27
 
32  
-			server.CurrentDatabaseChanged += delegate
  28
+			Server.CurrentDatabaseChanged += delegate
33 29
 			{
34 30
 				Initialize();
35 31
 			};
@@ -61,7 +57,7 @@ public string Status
61 57
 
62 58
 		Task<JsonDocument[]> GetDocumentsQuery(int start, int pageSize)
63 59
 		{
64  
-			using (var session = server.OpenSession())
  60
+			using (var session = Server.OpenSession())
65 61
 				return session.Advanced.AsyncDatabaseCommands
66 62
 					.GetDocumentsAsync(start, pageSize);
67 63
 		}
@@ -81,7 +77,7 @@ void IHandle<DocumentDeleted>.Handle(DocumentDeleted message)
81 77
 		public void CreateNewDocument()
82 78
 		{
83 79
 			var doc = IoC.Get<EditDocumentViewModel>();
84  
-			events.Publish(new DatabaseScreenRequested(() => doc));
  80
+			Events.Publish(new DatabaseScreenRequested(() => doc));
85 81
 		}
86 82
 
87 83
 		public bool HasDocuments { get { return Documents.Any(); } }
@@ -90,7 +86,7 @@ protected override void OnActivate()
90 86
 		{
91 87
 			if (Documents == null) return;
92 88
 
93  
-			var countOfDocuments = server.Statistics.CountOfDocuments;
  89
+			var countOfDocuments = Server.Statistics.CountOfDocuments;
94 90
 
95 91
 			Status = countOfDocuments == 0
96 92
 				? "The database contains no documents."
14  Raven.Studio/Features/Documents/DocumentViewModel.cs