view directmapping/src/test/scala/DirectMappingTest.scala @ 264:060df0861705

~ fix the access to the default configuration file + error message more readable in case of malformed generated SQL query
author Alexandre Bertails <bertails@w3.org>
date Wed, 03 Nov 2010 15:58:58 -0400
parents 86d60884a3e7
children 18e140f8fd6f
line wrap: on
line source
package org.w3.sw.directmapping

import org.w3.sw.rdf._
import org.w3.sw.rdb.RDB._
import org.w3.sw.sql.SqlParser
import org.w3.sw.directmapping.DirectMapping._

import org.scalatest.FunSuite

class Test extends FunSuite {

  implicit def l2db (rs:List[Relation]):Map[RelName, Relation] =
    rs.map(r => (r.name -> r)).toMap
  implicit def string2relName (n:String) = RelName(n)
  implicit def string2attrName (n:String) = AttrName(n)

  test("2 People 1 Addresses") {

    val p = SqlParser()
    val s = """
CREATE TABLE Addresses (ID INT PRIMARY KEY, city STRING, state STRING);
INSERT INTO Addresses (ID, city, state) VALUES (18, "Cambridge", "MA");
CREATE TABLE People (ID INT PRIMARY KEY, fname STRING, addr INT, FOREIGN KEY (addr) REFERENCES Addresses(ID));
INSERT INTO People (ID, fname, addr) VALUES (7, "Bob", 18);
INSERT INTO People (ID, fname, addr) VALUES (8, "Sue", NULL);
"""
    val db = p.parseAll(p.ddl, s).get
    val g = directDB(StemIRI("http://foo.example/DB"), db)

    val expected:Graph =
      Set(
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#ID"),TypedLiteral("7",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#fname"),TypedLiteral("Bob",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#addr"),IRI("http://foo.example/DB/Addresses/ID.18#_")),
	Triple(IRI("http://foo.example/DB/People/ID.8#_"),IRI("http://foo.example/DB/People#ID"),TypedLiteral("8",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/People/ID.8#_"),IRI("http://foo.example/DB/People#fname"),TypedLiteral("Sue",IRI("http://www.w3.org/2001/XMLSchema#string"))), 

	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#ID"),TypedLiteral("18",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#city"),TypedLiteral("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#state"),TypedLiteral("MA",IRI("http://www.w3.org/2001/XMLSchema#string")))
      )
    assert (expected === g)
  }


  test("2 People 1 Addresses 1 Department") {

    val p = SqlParser()
    val s = """
CREATE TABLE Addresses (ID INT PRIMARY KEY, city STRING, state STRING);
INSERT INTO Addresses (ID, city, state) VALUES (18, "Cambridge", "MA");
CREATE TABLE Department (ID INT PRIMARY KEY, name STRING, city STRING,
                         manager INT, FOREIGN KEY (manager) REFERENCES People(ID), UNIQUE (name, city));
INSERT INTO Department (ID, name, city, manager) VALUES (23, "accounting", "Cambridge", 8);
CREATE TABLE People (ID INT PRIMARY KEY, fname STRING,
                     addr INT, FOREIGN KEY (addr) REFERENCES Addresses(ID),
                     deptName STRING, deptCity STRING, FOREIGN KEY (deptName, deptCity) REFERENCES Department(name, city));
INSERT INTO People (ID, fname, addr, deptName, deptCity) VALUES (7, "Bob", 18, "accounting", "Cambridge");
INSERT INTO People (ID, fname, addr, deptName, deptCity) VALUES (8, "Sue", NULL, NULL, NULL);
"""
    val db = p.parseAll(p.ddl, s).get
    val g = directDB(StemIRI("http://foo.example/DB"), db)

    val expected:Graph =
      Set(
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#deptName"),TypedLiteral("accounting",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#deptCity"),TypedLiteral("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#deptName_deptCity"),IRI("http://foo.example/DB/Department/ID.23#_")),

	Triple(IRI("http://foo.example/DB/Department/ID.23#_"),IRI("http://foo.example/DB/Department#ID"),TypedLiteral("23",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Department/ID.23#_"),IRI("http://foo.example/DB/Department#name"),TypedLiteral("accounting",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/Department/ID.23#_"),IRI("http://foo.example/DB/Department#city"),TypedLiteral("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/Department/ID.23#_"),IRI("http://foo.example/DB/Department#manager"),IRI("http://foo.example/DB/People/ID.8#_")),

	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#ID"),TypedLiteral("7",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#fname"),TypedLiteral("Bob",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#addr"),IRI("http://foo.example/DB/Addresses/ID.18#_")),
	Triple(IRI("http://foo.example/DB/People/ID.8#_"),IRI("http://foo.example/DB/People#ID"),TypedLiteral("8",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/People/ID.8#_"),IRI("http://foo.example/DB/People#fname"),TypedLiteral("Sue",IRI("http://www.w3.org/2001/XMLSchema#string"))), 

	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#ID"),TypedLiteral("18",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#city"),TypedLiteral("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#state"),TypedLiteral("MA",IRI("http://www.w3.org/2001/XMLSchema#string")))
      )
    assert (expected === g)
  }


  test("2 People 1 Addresses 1 Department 2 Projects 1 Task") {

    val p = SqlParser()
    val s = """
CREATE TABLE Addresses (ID INT PRIMARY KEY, city STRING, state STRING);
INSERT INTO Addresses (ID, city, state) VALUES (18, "Cambridge", "MA");
CREATE TABLE Department (ID INT PRIMARY KEY, name STRING, city STRING, manager INT,
                         FOREIGN KEY (manager) REFERENCES People(ID),
                         UNIQUE (name, city));
INSERT INTO Department (ID, name, city, manager) VALUES (23, "accounting", "Cambridge", 8);
CREATE TABLE People (ID INT PRIMARY KEY, fname STRING, addr INT,
                     FOREIGN KEY (addr) REFERENCES Addresses(ID),
                     deptName STRING, deptCity STRING,
                     FOREIGN KEY (deptName, deptCity) REFERENCES Department(name, city));
INSERT INTO People (ID, fname, addr, deptName, deptCity) VALUES (7, "Bob", 18, "accounting", "Cambridge");
INSERT INTO People (ID, fname, addr, deptName, deptCity) VALUES (8, "Sue", NULL, NULL, NULL);
CREATE TABLE Projects (lead INT,
                       FOREIGN KEY (lead) REFERENCES People(ID),
                       name STRING, UNIQUE (lead, name), 
                       deptName STRING, deptCity STRING,
                       UNIQUE (name, deptName, deptCity),
                       FOREIGN KEY (deptName, deptCity) REFERENCES Department(name, city));
INSERT INTO Projects (lead, name, deptName, deptCity) VALUES (8, "pencil survey", "accounting", "Cambridge");
INSERT INTO Projects (lead, name, deptName, deptCity) VALUES (8, "eraser survey", "accounting", "Cambridge");
CREATE TABLE TaskAssignments (worker INT,
                              FOREIGN KEY (worker) REFERENCES People(ID),
                              project STRING, PRIMARY KEY (worker, project), 
                              deptName STRING, deptCity STRING,
                              FOREIGN KEY (worker) REFERENCES People(ID),
                              FOREIGN KEY (project, deptName, deptCity) REFERENCES Projects(name, deptName, deptCity),
                              FOREIGN KEY (deptName, deptCity) REFERENCES Department(name, city));
INSERT INTO TaskAssignments (worker, project, deptName, deptCity) VALUES (7, "pencil survey", "accounting", "Cambridge");
"""
    val db = p.parseAll(p.ddl, s).get
    val g = directDB(StemIRI("http://foo.example/DB"), db)

    val expected:Graph =
      Set(
	Triple(BNode("a"), IRI("http://foo.example/DB/Projects#lead"), IRI("http://foo.example/DB/People/ID.8#_")),
	Triple(BNode("a"), IRI("http://foo.example/DB/Projects#name"), TypedLiteral("pencil survey", IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(BNode("a"), IRI("http://foo.example/DB/Projects#deptName"), TypedLiteral("accounting", IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(BNode("a"), IRI("http://foo.example/DB/Projects#deptCity"), TypedLiteral("Cambridge", IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(BNode("a"), IRI("http://foo.example/DB/Projects#deptName_deptCity"), IRI("http://foo.example/DB/Department/ID.23#_")),

	Triple(BNode("b"), IRI("http://foo.example/DB/Projects#lead"), IRI("http://foo.example/DB/People/ID.8#_")),
	Triple(BNode("b"), IRI("http://foo.example/DB/Projects#name"), TypedLiteral("eraser survey", IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(BNode("b"), IRI("http://foo.example/DB/Projects#deptName"), TypedLiteral("accounting", IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(BNode("b"), IRI("http://foo.example/DB/Projects#deptCity"), TypedLiteral("Cambridge", IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(BNode("b"), IRI("http://foo.example/DB/Projects#deptName_deptCity"), IRI("http://foo.example/DB/Department/ID.23#_")),

	Triple(IRI("http://foo.example/DB/TaskAssignments/worker.7_project.pencil+survey#_"), IRI("http://foo.example/DB/TaskAssignments#worker"), IRI("http://foo.example/DB/People/ID.7#_")),
	Triple(IRI("http://foo.example/DB/TaskAssignments/worker.7_project.pencil+survey#_"), IRI("http://foo.example/DB/TaskAssignments#project"), TypedLiteral("pencil survey", IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/TaskAssignments/worker.7_project.pencil+survey#_"), IRI("http://foo.example/DB/TaskAssignments#deptName"), TypedLiteral("accounting", IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/TaskAssignments/worker.7_project.pencil+survey#_"), IRI("http://foo.example/DB/TaskAssignments#deptCity"), TypedLiteral("Cambridge", IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/TaskAssignments/worker.7_project.pencil+survey#_"), IRI("http://foo.example/DB/TaskAssignments#deptName_deptCity"), IRI("http://foo.example/DB/Department/ID.23#_")),
	Triple(IRI("http://foo.example/DB/TaskAssignments/worker.7_project.pencil+survey#_"), IRI("http://foo.example/DB/TaskAssignments#project_deptName_deptCity"), BNode("a")),

	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#deptName"),TypedLiteral("accounting",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#deptCity"),TypedLiteral("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#deptName_deptCity"),IRI("http://foo.example/DB/Department/ID.23#_")),

	Triple(IRI("http://foo.example/DB/Department/ID.23#_"),IRI("http://foo.example/DB/Department#ID"),TypedLiteral("23",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Department/ID.23#_"),IRI("http://foo.example/DB/Department#name"),TypedLiteral("accounting",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/Department/ID.23#_"),IRI("http://foo.example/DB/Department#city"),TypedLiteral("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/Department/ID.23#_"),IRI("http://foo.example/DB/Department#manager"),IRI("http://foo.example/DB/People/ID.8#_")),

	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#ID"),TypedLiteral("7",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#fname"),TypedLiteral("Bob",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#addr"),IRI("http://foo.example/DB/Addresses/ID.18#_")),
	Triple(IRI("http://foo.example/DB/People/ID.8#_"),IRI("http://foo.example/DB/People#ID"),TypedLiteral("8",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/People/ID.8#_"),IRI("http://foo.example/DB/People#fname"),TypedLiteral("Sue",IRI("http://www.w3.org/2001/XMLSchema#string"))), 

	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#ID"),TypedLiteral("18",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#city"),TypedLiteral("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#state"),TypedLiteral("MA",IRI("http://www.w3.org/2001/XMLSchema#string")))
      )
    assert (expected === g)
  }


  test("1 People 1 Addresses 1 Offices") {

    val p = SqlParser()
    val s = """
CREATE TABLE Addresses (ID INT PRIMARY KEY, city STRING, state STRING);
INSERT INTO Addresses (ID, city, state) VALUES (18, "Cambridge", "MA");
CREATE TABLE People (ID INT PRIMARY KEY, fname STRING, addr INT,
                     FOREIGN KEY (addr) REFERENCES Addresses(ID));
INSERT INTO People (ID, fname, addr) VALUES (7, "Bob", 18);
CREATE TABLE Offices (ID INT PRIMARY KEY,
                      building INT, ofcNumber STRING,
                      FOREIGN KEY (ID) REFERENCES Addresses(ID));
INSERT INTO Offices (ID, building, ofcNumber) VALUES (18, 32, "G528");
"""
    val db = p.parseAll(p.ddl, s).get
    val g = directDB(StemIRI("http://foo.example/DB"), db)

    val expected:Graph =
      Set(
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Offices#ID"),TypedLiteral("18",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Offices#building"),TypedLiteral("32",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Offices#ofcNumber"),TypedLiteral("G528",IRI("http://www.w3.org/2001/XMLSchema#string"))), 

	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#ID"),TypedLiteral("7",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#fname"),TypedLiteral("Bob",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#addr"),IRI("http://foo.example/DB/Addresses/ID.18#_")),

	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#ID"),TypedLiteral("18",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#city"),TypedLiteral("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#state"),TypedLiteral("MA",IRI("http://www.w3.org/2001/XMLSchema#string")))
      )
    assert (expected === g)
  }


  test("1 People 1 Addresses 1 Offices 1 ExectutiveOffices") {

    val p = SqlParser()
    val s = """
CREATE TABLE Addresses (ID INT PRIMARY KEY, city STRING, state STRING);
INSERT INTO Addresses (ID, city, state) VALUES (18, "Cambridge", "MA");
CREATE TABLE People (ID INT PRIMARY KEY, fname STRING, addr INT,
                     FOREIGN KEY (addr) REFERENCES Addresses(ID));
INSERT INTO People (ID, fname, addr) VALUES (7, "Bob", 18);
CREATE TABLE Offices (ID INT PRIMARY KEY,
                      building INT, ofcNumber STRING,
                      FOREIGN KEY (ID) REFERENCES Addresses(ID));
INSERT INTO Offices (ID, building, ofcNumber) VALUES (18, 32, "G528");
CREATE TABLE ExecutiveOffices (ID INT PRIMARY KEY,
                               desk STRING,
                               FOREIGN KEY (ID) REFERENCES Offices(ID));
INSERT INTO ExecutiveOffices (ID, desk) VALUES (18, "oak");
"""

    val db = p.parseAll(p.ddl, s).get
    val g = directDB(StemIRI("http://foo.example/DB"), db)

    val expected:Graph =
      Set(
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/ExecutiveOffices#ID"),TypedLiteral("18",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/ExecutiveOffices#desk"),TypedLiteral("oak",IRI("http://www.w3.org/2001/XMLSchema#string"))), 

	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Offices#ID"),TypedLiteral("18",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Offices#building"),TypedLiteral("32",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Offices#ofcNumber"),TypedLiteral("G528",IRI("http://www.w3.org/2001/XMLSchema#string"))), 

	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#ID"),TypedLiteral("7",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#fname"),TypedLiteral("Bob",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/People/ID.7#_"),IRI("http://foo.example/DB/People#addr"),IRI("http://foo.example/DB/Addresses/ID.18#_")),

	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#ID"),TypedLiteral("18",IRI("http://www.w3.org/2001/XMLSchema#int"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#city"),TypedLiteral("Cambridge",IRI("http://www.w3.org/2001/XMLSchema#string"))),
	Triple(IRI("http://foo.example/DB/Addresses/ID.18#_"),IRI("http://foo.example/DB/Addresses#state"),TypedLiteral("MA",IRI("http://www.w3.org/2001/XMLSchema#string")))
      )
    assert (expected === g)
  }


  test("NodeMap") {

    val ck1:CandidateKey = CandidateKey("name", "ssn")
    val ck2:CandidateKey = CandidateKey("ID")
    val v11:List[CellValue] = List(LexicalValue("bob"), LexicalValue("123"))
    val v21:List[CellValue] = List(LexicalValue("alice"), LexicalValue("8"))
    val v12:List[CellValue] = List(LexicalValue("18"))
    val v22:List[CellValue] = List(LexicalValue("23"))
    val s1:Node = BNode("1")
    val s2:Node = BNode("2")
    val data:Set[(List[(CandidateKey, List[CellValue])], Node)] =
      Set((List((ck1, v11),(ck2, v21)), s1),
	  (List((ck1, v12),(ck2, v22)), s2))
    val test = data.foldLeft(KeyMap(Map[CandidateKey,  Map[List[CellValue], Node]]()))((m, t) => m ++ (t._1, t._2))

    val goal:KeyMap = KeyMap(
      Map(ck1 -> Map(v11 -> s1,
      		     v12 -> s2),
      	  ck2 -> Map(v21 -> s1,
      		     v22 -> s2))
    )
    assert(goal === test)
  }

}
Set up and maintained by W3C Systems Team, please report bugs to sysreq@w3.org.

W3C would like to thank Microsoft who donated the server that allows us to run this service.