void IDataRepository.Add(ReportData report)
        {
            using (var cmd = _connection.CreateCommand())
            {
                cmd.CommandText = "INSERT INTO report(guid, name, created_at, created_by, contents) VALUES(@1, @2, @3, @4, @5);";

                cmd.Parameters.AddWithValue("@1", report.Guid.ToString());
                cmd.Parameters.AddWithValue("@2", report.Name);
                cmd.Parameters.AddWithValue("@3", report.CreatedAt.UtcTicks);
                cmd.Parameters.AddWithValue("@4", report.CreatedBy);
                cmd.Parameters.AddWithValue("@5", report.Definition);

                cmd.ExecuteNonQuery();
            }
        }
        public JsonResult Create(CreateReportModel model)
        {
            IReportTemplate template = _templateFactory.Create(new DescriptionMetadata() { Name = model.Name, Author = model.CreatedBy });
            template.DataSources.Set(new DataSource("", new StaticDataProvider().Set("test", 4711).Set("switch", true)));

            // Un-comment this to add a data provider which returns a DataSet with data filled by a custom script written in C#.
            //template.DataSources.Set(new DataSource("scr1", new ScriptDataProvider()
            //{
            //    ScriptTypeKey = "cs",
            //    ScriptText = @"DataSet result = new DataSet(""Created from code""); result.Tables.Add(""Hello world""); return result;"
            //}));

            IReportTemplateSection section = template.Sections.GetSection(SectionType.Detail);

            ICompositionElement rootElement = new VerticalContainerElement();
            rootElement.Set("data-source", "");
            rootElement.AddChild(new StaticLabelElement() { Value = "Hello, world!" });
            rootElement.AddChild(new TableElement() { DataSource = "ours" });
            section.RootElement = rootElement;

            string definition = null;

            using (StreamReader reader = new StreamReader(_templateFactory.Save(template)))
            {
                definition = reader.ReadToEnd();
            }

            ReportData rd = new ReportData()
            {
                Name = model.Name,
                Guid = Guid.NewGuid(),
                CreatedAt = DateTimeOffset.Now,
                CreatedBy = model.CreatedBy,
                Definition = definition
            };

            using (IDataRepository repository = GetRepository())
            {
                repository.Add(rd);
            }

            return Json(new { success = true, name = rd.Name, guid = rd.Guid }, JsonRequestBehavior.AllowGet);
        }
        private static ReportData DataRowToReport(DataRow row, bool includeDefinition)
        {
            ReportData report = new ReportData();

            try
            {
                report.Id = (int)row.Field<long>("id");
                report.Guid = new Guid(row.Field<string>("guid"));
                report.Name = row.Field<string>("name");
                report.CreatedAt = new DateTimeOffset(row.Field<long>("created_at"), TimeSpan.Zero);
                report.CreatedBy = row.Field<string>("created_by");

                if (includeDefinition)
                {
                    report.Definition = Encoding.UTF8.GetString(row.Field<byte[]>("contents"));
                }
            }
            catch (Exception)
            {
                report.State = EntityState.Erroneous;
            }

            return report;
        }