#!/usr/bin/env python2.4

import RDF
import sys

__author__= "Yoan Blanc <yoan at dosimple dot ch>"
__revision__= "20061230"

# Active RDF do this by itself!

class Resource(object):
	def __init__(self, uri):
		self.uri = uri

class Person(Resource):
	"""A person"""
	
	def __init__(self, uri, **kwargs):
		super(Person, self).__init__(uri)
		
		for k,v in kwargs.iteritems():
			setattr(self, k, v)
	
	@classmethod
	def find_all(cls, model, namespace):
		querystring = 'PREFIX test: <%s> \
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
SELECT ?person, ?name WHERE \
	{ ?person rdf:type test:Person ; test:name ?name . }' % (namespace,)
		query = RDF.SPARQLQuery(querystring)
  		persons = []
  		for person in query.execute(model):
  			persons.append(Person(person["person"].uri, name=person["name"]))
	  	return persons
	
	@classmethod
	def find_by_name(cls, model, name, namespace):
		querystring = 'PREFIX test: <%s> \
SELECT ?person WHERE \
  { ?person rdf:type test:Person ; test:name "%s" . }' % (namespace, name)
  		query = RDF.SPARQLQuery(querystring)
  		persons = []
  		for person in query.execute(model):
	  		persons.append(Person(person["person"].uri, name=name))
	  	return persons

class Male(Person):
	"""A male"""
	
	@classmethod
	def find_all(cls, model, namespace):
		querystring = 'PREFIX test: <%s> \
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
SELECT ?male, ?name WHERE \
	{ ?male rdf:type test:Male ; test:name ?name . }' % (namespace,)
		query = RDF.SPARQLQuery(querystring)
  		males = []
  		for male in query.execute(model):
  			males.append(Person(male["male"].uri, name=male["name"]))
	  	return males
	
	@classmethod
	def find_by_name(cls, model, name, namespace):
		querystring = 'PREFIX test: <%s> \
SELECT ?male WHERE \
  { ?male rdf:type test:Male ; test:name "%s" . }' % (namespace, name)
  		query = RDF.SPARQLQuery(querystring)
  		males = []
  		for male in query.execute(model):
	  		males.append(Person(male["male"].uri, name=name))
	  	return persons

# ConnectionPool or Adapter,... whatever it's a mix
class DB(object):
	"""The db wrapper"""
	def __init__(self, model, namespace):
		self.ns = namespace
		self.RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
		self.RDFS = "http://www.w3.org/2000/01/rdf-schema#"
		
		self.storage = RDF.Storage(storage_name="sqlite", name="foo.db", options_string="")
		self.model = RDF.Model(self.storage)
		
		uri=RDF.Uri(string="file:"+model)
		parser = RDF.Parser()
		for s in parser.parse_as_stream(uri,uri):
			self.model.add_statement(s)
	
	def add_male(self, male):
		"""Add this male to the model"""
		s_type = RDF.Statement(RDF.Uri(male.uri), RDF.Uri(self.RDF+"type"), RDF.Uri(self.ns+"Male"))
		s_name = RDF.Statement(RDF.Uri(male.uri), RDF.Uri(self.ns+"name"), RDF.Node(male.name))
		self.model.add_statement(s_type)
		self.model.add_statement(s_name)
	
	def add_person(self, person):
		"""Add this person to the model"""
		s_type = RDF.Statement(RDF.Uri(person.uri), RDF.Uri(self.RDF+"type"), RDF.Uri(self.ns+"Person"))
		s_name = RDF.Statement(RDF.Uri(person.uri), RDF.Uri(self.ns+"name"), RDF.Node(person.name))
		self.model.add_statement(s_type)
		self.model.add_statement(s_name)
	
	def find_all_males(self):
		"""Find all males"""
		return Male.find_all(self.model, self.ns)
	
	def find_males_by_name(self, name):
		"""Find a male by its name"""
		return Male.find_by_name(self.model, name, self.ns) 
	
	def find_all_persons(self):
		"""Find all persons"""
		return Person.find_all(self.model, self.ns)
	
	def find_persons_by_name(self, name):
		"""Find a person by its name"""
		return Person.find_by_name(self.model, name, self.ns) 

def main(argv):
	db = DB("model.rdf", "http://yoan.dosimple.ch/beta/test.rdfs#")
	
	yoan = Person("http://yoan.dosimple.ch/", name="Yoan")
	batiste = Male("http://batiste.dosimple.ch/", name="Batiste")
	
	db.add_person(yoan)
	db.add_male(batiste)
	
	print "Find all Persons:"
	all_males = db.find_all_males()
	all_persons = all_males + db.find_all_persons() # need to do this by hand, grrr!
	for p in all_persons:
		print " %s: %s" % (p.uri, p.name)
	print
	
	print "Find all Males:"
	for p in all_males:
		print " %s: %s" % (p.uri, p.name)
	print

if __name__ == "__main__":
	main(sys.argv)

