5 // Gabriel Burt <gabriel.burt@gmail.com>
7 // Copyright (c) 2010 Novell, Inc.
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 using Hyena
.Data
.Sqlite
;
29 using System
.Collections
;
33 public class SampleModel
: ICacheableDatabaseModel
35 public string ReloadFragment { get; set; }
36 public string SelectAggregates { get; set; }
37 public string JoinTable { get; set; }
38 public string JoinFragment { get; set; }
39 public string JoinPrimaryKey { get; set; }
40 public string JoinColumn { get; set; }
41 public bool CachesJoinTableEntries { get; set; }
42 public bool CachesValues { get; set; }
44 public int FetchCount
{
47 public Hyena
.Collections
.Selection Selection { get; private set; }
49 public SqliteModelCache
<MultiUserSample
> Cache { get; private set; }
51 private static int id
;
53 public SampleModel (string condition
, Database db
, string aggregates
)
55 Selection
= new Hyena
.Collections
.Selection ();
56 ReloadFragment
= String
.Format ("FROM Samples {0}", condition
);
57 SelectAggregates
= aggregates
;
58 Cache
= new SqliteModelCache
<MultiUserSample
> (db
, (id
++).ToString (), this, db
.SampleProvider
);
64 Cache
.UpdateAggregates ();
68 public class MetricSampleModel
: SampleModel
70 private Metric metric
;
71 public string MetricName { get; private set; }
72 public long MetricId { get { return metric.Id; }
}
74 private string condition
;
75 public MetricSampleModel (SqliteModelCache
<MultiUserSample
> limiter
, Database db
, string aggregates
) : base (null, db
, aggregates
)
77 condition
= String
.Format (
78 "FROM Samples, HyenaCache WHERE Samples.MetricID = {0} AND HyenaCache.ModelID = {1} AND Samples.ID = HyenaCache.ItemID",
79 "{0}", limiter
.CacheId
83 public void ChangeMetric (Database db
, string metricName
)
85 MetricName
= metricName
;
86 metric
= db
.GetMetric (metricName
);
87 ReloadFragment
= String
.Format (condition
, metric
.Id
);
92 public class MetaMetrics
94 string fmt
= "{0,20}";
96 public MetaMetrics (Database db
)
98 var latest_samples
= new SampleModel ("GROUP BY UserID, MetricID ORDER BY stamp desc", db
, "COUNT(DISTINCT(UserID)), MIN(Stamp), MAX(Stamp)");
99 latest_samples
.Cache
.AggregatesUpdated
+= (reader
) => {
100 Console
.WriteLine ("Total unique users for this time slice: {0}", reader
[1]);
101 Console
.WriteLine ("First report was on {0}", SqliteUtils
.FromDbFormat (typeof(DateTime
), reader
[2]));
102 Console
.WriteLine ("Last report was on {0}", SqliteUtils
.FromDbFormat (typeof(DateTime
), reader
[3]));
103 Console
.WriteLine ();
105 latest_samples
.Reload ();
107 var string_summary
= new MetricSampleModel (latest_samples
.Cache
, db
,
108 @"COUNT(DISTINCT(UserID))"
110 string_summary
.Cache
.AggregatesUpdated
+= (agg_reader
) => {
111 Console
.WriteLine (String
.Format (" Users: {0}", fmt
), agg_reader
[1]);
112 using (var reader
= new HyenaDataReader (db
.Query (
113 @"SELECT COUNT(DISTINCT(UserId)) as users, Value FROM Samples, HyenaCache
114 WHERE MetricId = ? AND HyenaCache.ModelID = ? AND HyenaCache.ItemID = Samples.ID
115 GROUP BY Value ORDER BY users DESC", string_summary
.MetricId
, string_summary
.Cache
.CacheId
))) {
116 while (reader
.Read ()) {
117 Console
.WriteLine (" {0,-5}: {1,-20}", reader
.Get
<long> (0), reader
.Get
<string> (1));
120 Console
.WriteLine ();
123 var numeric_slice
= new MetricSampleModel (latest_samples
.Cache
, db
,
124 @"MIN(CAST(Value as NUMERIC)), MAX(CAST(Value as NUMERIC)),
125 AVG(CAST(Value as NUMERIC)), HYENA_METRICS_MEDIAN_DOUBLE(CAST(Value as NUMERIC)), COUNT(DISTINCT(UserID))"
128 numeric_slice
.Cache
.AggregatesUpdated
+= (reader
) => {
129 Console
.WriteLine (String
.Format (" Users: {0}", fmt
), reader
[5]);
130 Console
.WriteLine (String
.Format (" Min: {0}", fmt
), Metric
.ToString (numeric_slice
.MetricName
, reader
[1]));
131 Console
.WriteLine (String
.Format (" Avg: {0}", fmt
), Metric
.ToString (numeric_slice
.MetricName
, reader
[3]));
132 Console
.WriteLine (String
.Format (" Median: {0}", fmt
), Metric
.ToString (numeric_slice
.MetricName
, reader
[4]));
133 Console
.WriteLine (String
.Format (" Max: {0}", fmt
), Metric
.ToString (numeric_slice
.MetricName
, reader
[2]));
134 Console
.WriteLine ();
137 var metrics
= db
.QueryEnumerable
<string> ("SELECT Name FROM Metrics ORDER BY Name ASC");
138 foreach (var metric
in metrics
) {
139 switch (GetMetricType (metric
)) {
141 Console
.WriteLine ("{0}:", metric
);
142 string_summary
.ChangeMetric (db
, metric
);
144 //case "timespan" : SummarizeNumeric<TimeSpan> (metric); break;
145 //case "datetime" : SummarizeNumeric<DateTime> (metric); break;
147 Console
.WriteLine ("{0}:", metric
);
148 //SummarizeNumeric<long> (metric_cache);
149 numeric_slice
.ChangeMetric (db
, metric
);
152 //SummarizeNumeric<double> (metric_cache);
158 private string GetMetricType (string name
)
160 var lower_name
= name
.ToLower ();
161 foreach (var str
in new string [] { "avg", "count", "size", "width", "height", "duration", "playseconds", "_pos" }
) {
162 if (lower_name
.Contains (str
))
166 if (name
.EndsWith ("BuildTime"))
169 if (name
.EndsWith ("LongSqliteCommand") || name
.EndsWith ("At") || name
.StartsWith ("Assemblies/") ||
170 name
.EndsWith ("child_sort_id") || name
.EndsWith ("separate_by_type") || name
.EndsWith ("expanded"))