svn path=/trunk/moma-tool/; revision=107715
This commit is contained in:
Dick Porter 2008-07-11 12:43:06 +00:00
Коммит d245d436d7
10 изменённых файлов: 1059 добавлений и 0 удалений

43
IssueTypeLookups.sql Normal file
Просмотреть файл

@ -0,0 +1,43 @@
INSERT INTO issue_type (
lookup_name,
display_name,
description
)
VALUES (
'MISS',
'Missing Method',
'The application relies on a method that is not yet implemented in Mono. The application will not be able to run with this dependency.'
);
INSERT INTO issue_type (
lookup_name,
display_name,
description
)
VALUES (
'NIEX',
'NotImplementedException',
'The application relies on a method which exists, but will throw a NotImplementedException if called. The application may run with this issue; however, the application will likely crash if the code that relies on this method is executed.'
);
INSERT INTO issue_type (
lookup_name,
display_name,
description
)
VALUES (
'PINV',
'P/Invoke',
'The application relies on a non-managed library. If the library has not been ported to the target platform, this application will not be able to run.'
);
INSERT INTO issue_type (
lookup_name,
display_name,
description
)
VALUES (
'TODO',
'Method marked MonoTodo',
'The application relies on a method that has been implemented in Mono, but which has been marked with the [MonoTodo] attribute. This method may exhibit unexpected behavior if the code that relies on this method is executed.'
);

26
Makefile Normal file
Просмотреть файл

@ -0,0 +1,26 @@
ASS_SRCS=\
MomaTool.Database/Issue.cs \
MomaTool.Database/IssueType.cs \
MomaTool.Database/MomaDefinition.cs \
MomaTool.Database/Report.cs
ASS_ASSES=-r:Castle.ActiveRecord.dll -r:NHibernate.dll
ASS=MomaTool.Database.dll
TEST_SRCS=test.cs
TEST_ASSES=-r:$(ASS) $(ASS_ASSES)
TEST=test.exe
DBINS_SRCS=dbinsert.cs
DBINS_ASSES=-r:$(ASS) $(ASS_ASSES)
DBINS=dbinsert.exe
all: $(ASS) $(TEST) $(DBINS)
$(ASS): $(ASS_SRCS)
gmcs -out:$(ASS) -target:library $(ASS_SRCS) $(ASS_ASSES)
$(TEST): $(TEST_SRCS) $(ASS)
gmcs -out:$(TEST) $(TEST_SRCS) $(TEST_ASSES)
$(DBINS): $(DBINS_SRCS) $(ASS)
gmcs -out:$(DBINS) $(DBINS_SRCS) $(DBINS_ASSES)

131
MomaTool.Database/Issue.cs Normal file
Просмотреть файл

@ -0,0 +1,131 @@
using System;
using Castle.ActiveRecord;
using NHibernate.Expression;
namespace MomaTool.Database
{
[ActiveRecord ("issue")]
public class Issue : ActiveRecordBase<Issue>
{
private int id;
private string method_return_type;
private string method_namespace;
private string method_class;
private string method_name;
private string method_library;
private Report report;
private IssueType issue_type;
[PrimaryKey (PrimaryKeyType.Sequence, SequenceName="issue_id_seq")]
public int Id
{
get {
return id;
}
set {
id = value;
}
}
[Property ("method_return_type", Length=200)]
public String MethodReturnType
{
get {
return method_return_type;
}
set {
method_return_type = value;
}
}
[Property ("method_namespace", Length=200)]
public String MethodNamespace
{
get {
return method_namespace;
}
set {
method_namespace = value;
}
}
[Property ("method_class", Length=200)]
public String MethodClass
{
get {
return method_class;
}
set {
method_class = value;
}
}
[Property ("method_name", Length=1000)]
public String MethodName
{
get {
return method_name;
}
set {
method_name = value;
}
}
[Property ("method_library", Length=500)]
public String MethodLibrary
{
get {
return method_library;
}
set {
method_library = value;
}
}
[BelongsTo ("report_id", ForeignKey="fk_issue_report", Cascade=CascadeEnum.All, NotNull=true)]
public Report Report
{
get {
return report;
}
set {
report = value;
}
}
[BelongsTo ("issue_type_id", ForeignKey="fk_issue_issue_type", Cascade=CascadeEnum.All, NotNull=true)]
public IssueType IssueType
{
get {
return issue_type;
}
set {
issue_type = value;
}
}
/* Accessor functions */
public static Issue FindById (int id)
{
return(FindOne (Expression.Eq ("Id", id)));
}
public static Issue Create (Report report, IssueType type, string return_type, string ns, string class_name, string method_name, string library)
{
Issue ret = new Issue ();
ret.Report = report;
ret.IssueType = type;
ret.MethodReturnType = return_type;
ret.MethodNamespace = ns;
ret.MethodClass = class_name;
ret.MethodName = method_name;
ret.MethodLibrary = library;
ret.Save ();
return ret;
}
}
}

Просмотреть файл

@ -0,0 +1,82 @@
using System;
using Castle.ActiveRecord;
using NHibernate.Expression;
namespace MomaTool.Database
{
[ActiveRecord ("issue_type")]
public class IssueType : ActiveRecordBase<IssueType>
{
private int id;
private string lookup_name;
private string display_name;
private string description;
private bool is_active;
[PrimaryKey (PrimaryKeyType.Sequence, SequenceName="issue_type_id_seq")]
public int Id
{
get {
return id;
}
set {
id = value;
}
}
[Property ("lookup_name", NotNull=true, Length=10)]
public String LookupName
{
get {
return lookup_name;
}
set {
lookup_name = value;
}
}
[Property ("display_name", NotNull=true, Length=100)]
public String DisplayName
{
get {
return display_name;
}
set {
display_name = value;
}
}
[Property ("description", SqlType="Text", NotNull=true)]
public String Description
{
get {
return description;
}
set {
description = value;
}
}
[Property ("is_active", NotNull=true)]
public bool IsActive
{
get {
return is_active;
}
set {
is_active = value;
}
}
/* Accessor functions */
public static IssueType FindById (int id)
{
return(FindOne (Expression.Eq ("Id",id)));
}
public static IssueType FindByLookupName (string name)
{
return(FindOne (Expression.Eq ("LookupName", name)));
}
}
}

Просмотреть файл

@ -0,0 +1,121 @@
using System;
using Castle.ActiveRecord;
using NHibernate.Expression;
namespace MomaTool.Database
{
[ActiveRecord ("moma_definition")]
public class MomaDefinition : ActiveRecordBase<MomaDefinition>
{
private int id;
private string lookup_name;
private string display_name;
private string description;
private DateTime create_date;
private bool is_active;
[PrimaryKey (PrimaryKeyType.Sequence, SequenceName="moma_definition_id_seq")]
public int Id
{
get {
return id;
}
set {
id = value;
}
}
[Property ("lookup_name", NotNull=true, Length=100)]
public String LookupName
{
get {
return lookup_name;
}
set {
lookup_name = value;
}
}
[Property ("display_name", NotNull=true, Length=100)]
public String DisplayName
{
get {
return display_name;
}
set {
display_name = value;
}
}
[Property ("description", NotNull=true, SqlType="Text")]
public String Description
{
get {
return description;
}
set {
description = value;
}
}
[Property ("create_date", NotNull=true)]
public DateTime CreateDate
{
get {
return create_date;
}
set {
create_date = value;
}
}
[Property ("is_active", NotNull=true)]
public bool IsActive
{
get {
return is_active;
}
set {
is_active = value;
}
}
/* Constructors */
/* Need a 0-arg constructor for NHibernate */
public MomaDefinition ()
{
this.CreateDate = DateTime.UtcNow;
this.IsActive = true;
}
public MomaDefinition (string name) : this()
{
this.LookupName = name;
this.DisplayName = name;
this.Description = name;
}
/* Accessor functions */
public static MomaDefinition FindById (int id)
{
return(FindOne (Expression.Eq ("Id", id)));
}
public static MomaDefinition FindByLookupName (string name)
{
return(FindOne (Expression.Eq ("LookupName", name)));
}
public static MomaDefinition GetOrCreate (string name)
{
MomaDefinition ret = FindByLookupName (name);
if (ret == null) {
ret = new MomaDefinition (name);
ret.Save ();
}
return ret;
}
}
}

217
MomaTool.Database/Report.cs Normal file
Просмотреть файл

@ -0,0 +1,217 @@
using System;
using Castle.ActiveRecord;
using NHibernate.Expression;
namespace MomaTool.Database
{
[ActiveRecord ("report")]
public class Report : ActiveRecordBase<Report>
{
private int id;
private string report_filename;
private DateTime report_date;
private string reporter_ip;
private string reporter_name;
private string reporter_email;
private string reporter_organisation;
private string reporter_homepage;
private string reporter_comments;
private DateTime create_date;
private DateTime last_update_date;
private bool is_active;
private MomaDefinition moma_definition;
[PrimaryKey (PrimaryKeyType.Sequence, SequenceName="report_id_seq")]
public int Id
{
get {
return id;
}
set {
id = value;
}
}
[Property ("report_filename", NotNull=true, Length=50)]
public String ReportFilename
{
get {
return report_filename;
}
set {
report_filename = value;
}
}
[Property ("report_date", NotNull=true)]
public DateTime ReportDate
{
get {
return report_date;
}
set {
report_date = value;
}
}
[Property ("reporter_ip", Length=50)]
public String ReporterIp
{
get {
return reporter_ip;
}
set {
reporter_ip = value;
}
}
[Property ("reporter_name", Length=500)]
public String ReporterName
{
get {
return reporter_name;
}
set {
reporter_name = value;
}
}
[Property ("reporter_email", Length=500)]
public String ReporterEmail
{
get {
return reporter_email;
}
set {
reporter_email = value;
}
}
[Property ("reporter_organization", Length=500)]
public String ReporterOrganisation
{
get {
return reporter_organisation;
}
set {
reporter_organisation = value;
}
}
[Property ("reporter_homepage", Length=500)]
public String ReporterHomepage
{
get {
return reporter_homepage;
}
set {
reporter_homepage = value;
}
}
[Property ("reporter_comments", SqlType="Text")]
public String ReporterComments
{
get {
return reporter_comments;
}
set {
reporter_comments = value;
}
}
[Property ("create_date", NotNull=true)]
public DateTime CreateDate
{
get {
return create_date;
}
set {
create_date = value;
}
}
[Property ("last_update_date", NotNull=true)]
public DateTime LastUpdateDate
{
get {
return last_update_date;
}
set {
last_update_date = value;
}
}
[Property ("is_active", NotNull=true)]
public bool IsActive
{
get {
return is_active;
}
set {
is_active = value;
}
}
[BelongsTo ("moma_definition_id", ForeignKey="fk_report_moma_definition", Cascade=CascadeEnum.All)]
public MomaDefinition MomaDefinition
{
get {
return moma_definition;
}
set {
moma_definition = value;
}
}
/* Constructors */
/* Need a 0-arg constructor for NHibernate */
public Report ()
{
this.CreateDate = DateTime.UtcNow;
this.IsActive = true;
}
/* Accessor functions */
public static Report FindById (int id)
{
return(FindOne (Expression.Eq ("Id", id)));
}
public static Report FindByReportFilename (string file)
{
return(FindOne (Expression.Eq ("ReportFilename", file)));
}
public static Report CreateOrUpdate (string file,
MomaDefinition def,
DateTime date, string ip,
string name, string email,
string org,
string homepage,
string comments)
{
Report ret = FindByReportFilename (file);
if (ret == null) {
ret = new Report ();
}
ret.MomaDefinition = def;
ret.ReportFilename = file;
ret.ReportDate = date;
ret.ReporterIp = ip;
ret.ReporterName = name;
ret.ReporterEmail = email;
ret.ReporterOrganisation = org;
ret.ReporterHomepage = homepage;
ret.ReporterComments = comments;
ret.LastUpdateDate = DateTime.UtcNow;
ret.Save ();
return ret;
}
}
}

189
dbinsert.cs Normal file
Просмотреть файл

@ -0,0 +1,189 @@
using System;
using System.IO;
using System.Globalization;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework.Config;
using MomaTool.Database;
namespace MomaTool
{
public class DBInsert
{
static IssueType miss;
static IssueType niex;
static IssueType pinv;
static IssueType todo;
public static void Main (string[] args)
{
XmlConfigurationSource source = new XmlConfigurationSource ("test_castle_config.xml");
Assembly ass = Assembly.Load ("MomaTool.Database");
ActiveRecordStarter.Initialize (ass, source);
//ActiveRecordStarter.CreateSchema ();
miss = IssueType.FindByLookupName ("MISS");
if(miss == null) {
Console.WriteLine ("Can't find issue type: MISS");
Environment.Exit (1);
}
niex = IssueType.FindByLookupName ("NIEX");
if(niex == null) {
Console.WriteLine ("Can't find issue type: NIEX");
Environment.Exit (1);
}
pinv = IssueType.FindByLookupName ("PINV");
if(pinv == null) {
Console.WriteLine ("Can't find issue type: PINV");
Environment.Exit (1);
}
todo = IssueType.FindByLookupName ("TODO");
if(todo == null) {
Console.WriteLine ("Can't find issue type: TODO");
Environment.Exit (1);
}
foreach (string f in args) {
/*Report dbrep = */ParseReport (f);
}
}
static Report ParseReport (string file)
{
Report dbrep;
using (FileStream fs = File.OpenRead (file)) {
MomaDefinition dbdef;
Dictionary<string,string> meta = new Dictionary<string,string>();
StreamReader stream = new StreamReader (fs);
CultureInfo cult = CultureInfo.CreateSpecificCulture ("en-US");
string date = stream.ReadLine ();
DateTime date_parsed = DateTime.Parse (date, cult);
string ip = stream.ReadLine ();
string r = ReadMeta (stream, meta);
try {
dbdef = MomaDefinition.GetOrCreate (meta["@Definitions"]);
} catch {
Console.WriteLine ("Exception when creating MomaDefinition: [{0}]", meta["@Definitions"]);
throw;
}
try {
dbrep = Report.CreateOrUpdate (Path.GetFileName (file), dbdef, date_parsed, ip, meta["@Name"], meta["@Email"], meta["@Organization"], meta["@HomePage"], meta["@Comments"]);
} catch {
Console.WriteLine ("Exception when creating Report: Date {0}, IP {1}, Name [{2}], Email [{3}], Organisation [{4}], Home page [{5}], Comments [{6}]", date_parsed.ToString (), ip, meta["@Name"], meta["@Email"], meta["@Organization"], meta["@HomePage"], meta["@Comments"]);
throw;
}
for(; r != null && r.Length > 6; r = stream.ReadLine ()) {
IssueType type;
if (r[r.Length - 1] == '\r') {
r = r.Substring (0, r.Length - 1);
}
switch(r.Substring (0, 6)) {
case "[TODO]":
type = todo;
break;
case "[NIEX]":
type = niex;
break;
case "[MISS]":
type = miss;
break;
case "[PINV]":
type = pinv;
break;
default:
continue;
}
string rest = r.Substring (7);
string ns = "";
string class_name = "";
string method_name = "";
string lib = "";
string return_type = "";
try {
string[] method_parts = rest.Split (' ');
return_type = method_parts[0];
string details = method_parts[1];
int colons = details.IndexOf ("::");
if (colons != -1) {
/* "::" was found */
method_name = details.Substring (colons+2);
string[] ns_parts = details.Substring (0, colons).Split ('.');
class_name = ns_parts[ns_parts.Length - 1];
for(int i = 0; i < ns_parts.Length - 1; i++) {
if (ns.Length > 0) {
ns += ".";
}
ns += ns_parts[i];
}
} else {
/* "::" not found */
method_parts = rest.Split ('-');
method_name = method_parts[0].Split (new char[]{' '}, 2)[1];
lib = method_parts[1];
}
} catch {
Console.WriteLine ("Error parsing [{0}] in file {1}", r, file);
/* Carry on parsing,
* no need to error
* out here
*/
continue;
}
try {
Issue.Create (dbrep, type, return_type, ns, class_name, method_name, lib);
} catch {
Console.WriteLine ("Exception when creating Issue in report {0}: {1} Return type [{2}], Namespace [{3}], Class [{4}], Method [{5}], Library [{6}]", file, type.DisplayName, return_type, ns, class_name, method_name, lib);
throw;
}
}
}
return(dbrep);
}
static string ReadMeta (StreamReader stream, Dictionary<string,string> meta)
{
string s;
while ((s = stream.ReadLine ()) != null) {
if (s.Length == 0 || s[0] == '[') {
return s;
}
if (s[0] != '@') {
return s;
}
int p = s.IndexOf (':');
string v = s.Substring (p + 2);
meta[s.Substring (0, p)] = v;
}
return s;
}
}
}

221
ddl.sql Normal file
Просмотреть файл

@ -0,0 +1,221 @@
CREATE DATABASE nhibernate WITH OWNER=dick ENCODING='UNICODE';
\connect nhibernate
CREATE PROCEDURAL LANGUAGE plpgsql;
DROP TABLE issue;
DROP TABLE report;
DROP TABLE moma_definition;
DROP TABLE issue_type;
DROP FUNCTION CreateOrUpdateReport (
p_moma_definition_id integer,
p_report_filename character varying(50),
p_report_date timestamp without time zone,
p_reporter_ip character varying(50),
p_reporter_name character varying(500),
p_reporter_email character varying(500),
p_reporter_organization character varying(500),
p_reporter_homepage character varying(500),
p_reporter_comments text
);
DROP FUNCTION GetOrCreateDefinition (p_lookup varchar(100));
DROP FUNCTION CreateIssue (
p_report_id integer,
p_issue_type_id integer,
p_method_return_type character varying(200),
p_method_namespace character varying(200),
p_method_class character varying(200),
p_method_name character varying(1000),
p_method_library character varying(500)
);
-- Table: issue_type
CREATE TABLE issue_type
(
id serial NOT NULL,
lookup_name character varying(10) NOT NULL,
display_name character varying(100) NOT NULL,
description text NOT NULL,
is_active boolean NOT NULL DEFAULT true,
CONSTRAINT pk_issue_type PRIMARY KEY (id)
);
-- Table: moma_definition
CREATE TABLE moma_definition
(
id serial NOT NULL,
lookup_name character varying(100) NOT NULL,
display_name character varying(100) NOT NULL,
description text NOT NULL,
create_date timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(3) with time zone,
is_active boolean NOT NULL DEFAULT true,
CONSTRAINT pk_moma_definition PRIMARY KEY (id)
);
CREATE TABLE report
(
id serial NOT NULL,
moma_definition_id integer,
report_filename character varying(50) NOT NULL,
report_date timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(3) with time zone,
reporter_ip character varying(50),
reporter_name character varying(500),
reporter_email character varying(500),
reporter_organization character varying(500),
reporter_homepage character varying(500),
reporter_comments text,
create_date timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(3) with time zone,
last_update_date timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(3) with time zone,
is_active boolean NOT NULL DEFAULT true,
CONSTRAINT pk_report PRIMARY KEY (id),
CONSTRAINT fk_report_moma_definition FOREIGN KEY (moma_definition_id)
REFERENCES moma_definition (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
);
-- Table: report
-- Table: issue
CREATE TABLE issue
(
id serial NOT NULL,
report_id integer NOT NULL,
issue_type_id integer NOT NULL,
method_return_type character varying(200),
method_namespace character varying(200),
method_class character varying(200),
method_name character varying(1000),
method_library character varying(500),
CONSTRAINT pk_issue PRIMARY KEY (id),
CONSTRAINT fk_issue_issue_type FOREIGN KEY (issue_type_id)
REFERENCES issue_type (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT fk_issue_report FOREIGN KEY (report_id)
REFERENCES report (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE FUNCTION GetOrCreateDefinition (p_lookup varchar(100)) RETURNS SETOF int AS $$
DECLARE
r RECORD;
BEGIN
IF NOT EXISTS (SELECT id FROM moma_definition WHERE lookup_name ILIKE p_lookup LIMIT 1) THEN
INSERT INTO moma_definition(lookup_name, display_name, description)
VALUES (p_lookup, p_lookup, p_lookup);
END IF;
FOR r IN SELECT id FROM moma_definition WHERE lookup_name ILIKE p_lookup LIMIT 1 LOOP
RETURN NEXT r.id;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION CreateOrUpdateReport (
p_moma_definition_id integer,
p_report_filename character varying(50),
p_report_date timestamp without time zone,
p_reporter_ip character varying(50),
p_reporter_name character varying(500),
p_reporter_email character varying(500),
p_reporter_organization character varying(500),
p_reporter_homepage character varying(500),
p_reporter_comments text
) RETURNS SETOF int AS $$
DECLARE
r RECORD;
BEGIN
IF EXISTS (SELECT id FROM report WHERE report_filename ILIKE p_report_filename LIMIT 1) THEN
UPDATE report
SET
moma_definition_id=p_moma_definition_id,
report_filename=p_report_filename,
report_date=p_report_date,
reporter_ip=p_reporter_ip,
reporter_name=p_reporter_name,
reporter_email=p_reporter_email,
reporter_organization=p_reporter_organization,
reporter_homepage=p_reporter_homepage,
reporter_comments=p_reporter_comments,
last_update_date=('now'::text)::timestamp(3)
WHERE report_filename=p_report_filename;
ELSE
INSERT INTO report(
moma_definition_id,
report_filename,
report_date,
reporter_ip,
reporter_name,
reporter_email,
reporter_organization,
reporter_homepage,
reporter_comments)
VALUES (
p_moma_definition_id,
p_report_filename,
p_report_date,
p_reporter_ip,
p_reporter_name,
p_reporter_email,
p_reporter_organization,
p_reporter_homepage,
p_reporter_comments);
DELETE FROM issue
WHERE id = (SELECT id FROM report WHERE report_filename ILIKE p_report_filename LIMIT 1);
END IF;
FOR r IN SELECT id FROM report WHERE report_filename ILIKE p_report_filename LIMIT 1 LOOP
RETURN NEXT r.id;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION CreateIssue (
p_report_id integer,
p_issue_type_id integer,
p_method_return_type character varying(200),
p_method_namespace character varying(200),
p_method_class character varying(200),
p_method_name character varying(1000),
p_method_library character varying(500)
) RETURNS SETOF int AS $$
DECLARE
pId int;
r RECORD;
BEGIN
INSERT INTO issue (
report_id,
issue_type_id,
method_return_type,
method_namespace,
method_class,
method_name,
method_library
)
VALUES (
p_report_id,
p_issue_type_id,
p_method_return_type,
p_method_namespace,
p_method_class,
p_method_name,
p_method_library
);
pId = currval('issue_id_seq');
FOR r IN SELECT pId AS id LOOP
RETURN NEXT r.id;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;

20
test.cs Normal file
Просмотреть файл

@ -0,0 +1,20 @@
using System;
using System.Reflection;
using MomaTool.Database;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework.Config;
namespace MomaTool
{
public class Tester
{
public static void Main ()
{
XmlConfigurationSource source = new XmlConfigurationSource ("test_castle_config.xml");
Assembly ass = Assembly.Load ("MomaTool.Database");
ActiveRecordStarter.Initialize (ass, source);
ActiveRecordStarter.CreateSchema ();
}
}
}

9
test_castle_config.xml Normal file
Просмотреть файл

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<activerecord>
<config>
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.NpgsqlDriver" />
<add key="hibernate.dialect" value="NHibernate.Dialect.PostgreSQLDialect" />
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
<add key="hibernate.connection.connection_string" value="Server=localhost;Database=nhibernate;User ID=dick;Password=test" />
</config>
</activerecord>