// // Database.cs // // Author: // Gabriel Burt // // Copyright (c) 2010 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using System; using Hyena; using Hyena.Metrics; using Hyena.Data.Sqlite; using Hyena.Json; using Mono.Data.Sqlite; using System.Collections.Generic; namespace metrics { public class Database { const string db_path = "metrics.db"; public static HyenaSqliteConnection Open () { HyenaSqliteCommand.LogAll = ApplicationContext.CommandLine.Contains ("debug-sql"); var db = new HyenaSqliteConnection (db_path); db.Execute ("PRAGMA cache_size = ?", 32768 * 2); db.Execute ("PRAGMA synchronous = OFF"); db.Execute ("PRAGMA temp_store = MEMORY"); db.Execute ("PRAGMA count_changes = OFF"); SampleProvider = new SqliteModelProvider (db, "Samples", true); return db; } public static bool Exists { get { return System.IO.File.Exists (db_path); } } public static SqliteModelProvider SampleProvider { get; private set; } public static void Import () { using (var db = Open ()) { var sample_provider = SampleProvider; db.BeginTransaction (); foreach (var file in System.IO.Directory.GetFiles ("data")) { Log.InformationFormat ("Importing {0}", file); try { var o = new Deserializer (System.IO.File.ReadAllText (file)).Deserialize () as JsonObject; string user_id = (string) o["ID"]; int format_version = (int) o["FormatVersion"]; if (format_version != MetricsCollection.FormatVersion) { Log.WarningFormat ("Ignoring user report with old FormatVersion: {0}", format_version); continue; } var metrics = o["Metrics"] as JsonObject; try { foreach (string metric_name in metrics.Keys) { var samples = metrics[metric_name] as JsonArray; foreach (JsonArray sample in samples) { sample_provider.Save (MultiUserSample.Import (user_id, metric_name, (string)sample[0], (object)sample[1])); } } } catch { throw; } } catch (Exception e) { Log.Exception (String.Format ("Failed to read {0}", file), e); } } db.CommitTransaction (); } } } [SqliteFunction (Name = "HYENA_METRICS_MEDIAN_LONG", FuncType = FunctionType.Aggregate, Arguments = 1)] internal class MedianFunctionLong : MedianFunction { } [SqliteFunction (Name = "HYENA_METRICS_MEDIAN_DOUBLE", FuncType = FunctionType.Aggregate, Arguments = 1)] internal class MedianFunctionDouble : MedianFunction { } [SqliteFunction (Name = "HYENA_METRICS_MEDIAN_DATETIME", FuncType = FunctionType.Aggregate, Arguments = 1)] internal class MedianFunctionDateTime : MedianFunction { } internal class MedianFunction : SqliteFunction { public override void Step (object[] args, int stepNumber, ref object contextData) { List list = null; if (contextData == null) { contextData = list = new List (); } else { list = contextData as List; } var val = (T)SqliteUtils.FromDbFormat (typeof(T), args[0]); list.Add (val); } public override object Final (object contextData) { var list = contextData as List; if (list == null || list.Count == 0) return null; list.Sort (); return list[list.Count / 2]; } } }