adding a method to nsIRDFCursor.cpp

This commit is contained in:
guha%netscape.com 1998-12-27 20:35:46 +00:00
Родитель d1465ef805
Коммит 489589a12b
3 изменённых файлов: 928 добавлений и 18 удалений

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

@ -22,7 +22,7 @@ LIBRARY_NAME=rdfbase_s
CPP_OBJS=\
.\$(OBJDIR)\nsContainerCursor.obj \
.\$(OBJDIR)\nsEmptyCursor.obj \
.\$(OBJDIR)\nsMemoryDataSource.obj \
.\$(OBJDIR)\nsInMemoryDataSource.obj \
.\$(OBJDIR)\nsRDFResourceManager.obj \
.\$(OBJDIR)\nsSimpleDataBase.obj \
.\$(OBJDIR)\rdfutil.obj \

905
rdf/base/src/nsDataBase.cpp Normal file
Просмотреть файл

@ -0,0 +1,905 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIRDFCursor.h"
#include "nsIRDFNode.h"
#include "nsIRDFDataBase.h"
#include "nsISupportsArray.h"
#include "nsRepository.h"
#include "nsVoidArray.h"
#include "prlog.h"
/*
XXX rvg --- chris, are you happy with this (I rewrote it).
A simple "database" implementation. An RDF database is just a
"strategy" pattern for combining individual data sources into a
collective graph.
1) A database is a sequence of data sources. The set of data sources
can be specified during creation of the database. Data sources
can also be added/deleted from a database later.
2) The aggregation mechanism is based on simple super-positioning of
the graphs from the datasources. If there is a conflict (i.e.,
data source A has a true arc from foo to bar while data source B
has a false arc from foo to bar), the data source that it earlier
in the sequence wins.
The implementation below doesn't really do this and needs to be
fixed.
*/
static NS_DEFINE_IID(kIRDFArcsInCursorIID, NS_IRDFARCSINCURSOR_IID);
static NS_DEFINE_IID(kIRDFArcsOutCursorIID, NS_IRDFARCSOUTCURSOR_IID);
static NS_DEFINE_IID(kIRDFAssertionCursorIID, NS_IRDFASSERTIONCURSOR_IID);
static NS_DEFINE_IID(kIRDFCursorIID, NS_IRDFCURSOR_IID);
static NS_DEFINE_IID(kIRDFDataBaseIID, NS_IRDFDATABASE_IID);
static NS_DEFINE_IID(kIRDFDataSourceIID, NS_IRDFDATASOURCE_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
////////////////////////////////////////////////////////////////////////
// MultiCursor
//
// This class encapsulates all of the behavior that is necessary to
// stripe a cursor across several different data sources, including
// checks to determine whether an negation in an "earlier" data
// source masks an assertion in a "later" data source.
//
class MultiCursor {
private:
nsIRDFDataSource* mDataSource0;
nsIRDFDataSource** mDataSources;
nsIRDFCursor* mCurrentCursor;
nsIRDFNode* mNextResult;
PRBool mNextTruthValue;
PRInt32 mNextDataSource;
PRInt32 mCount;
public:
MultiCursor(nsVoidArray& dataSources);
virtual ~MultiCursor(void);
NS_IMETHOD AdvanceImpl(void);
virtual nsresult
GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result) = 0;
virtual nsresult
IsCurrentNegatedBy(nsIRDFDataSource* ds0,
PRBool* result) = 0;
nsIRDFCursor*
GetCurrentCursor(void) {
return mCurrentCursor;
}
};
MultiCursor::MultiCursor(nsVoidArray& dataSources)
: mDataSource0(nsnull),
mDataSources(nsnull),
mCurrentCursor(nsnull),
mNextResult(nsnull),
mCount(0),
mNextDataSource(0)
{
mCount = dataSources.Count();
mDataSources = new nsIRDFDataSource*[mCount];
PR_ASSERT(mDataSources);
if (! mDataSources)
return;
for (PRInt32 i = 0; i < mCount; ++i) {
mDataSources[i] = NS_STATIC_CAST(nsIRDFDataSource*, dataSources[i]);
NS_ADDREF(mDataSources[i]);
}
mDataSource0 = mDataSources[0];
NS_ADDREF(mDataSource0);
}
MultiCursor::~MultiCursor(void)
{
NS_IF_RELEASE(mNextResult);
NS_IF_RELEASE(mCurrentCursor);
for (PRInt32 i = mCount - 1; i >= 0; --i) {
NS_IF_RELEASE(mDataSources[i]);
}
NS_IF_RELEASE(mDataSource0);
}
NS_IMETHODIMP
MultiCursor::AdvanceImpl(void)
{
nsresult rv;
while (mNextDataSource < mCount) {
if (! mCurrentCursor) {
// We don't have a current cursor, so create a new one on
// the next data source.
rv = GetCursor(mDataSources[mNextDataSource], &mCurrentCursor);
if (NS_FAILED(rv))
return rv;
}
do {
if (NS_FAILED(rv = mCurrentCursor->Advance())) {
// If we can't advance the current cursor, then either
// a catastrophic error occurred, or it's depleted. If
// it's just depleted break out of this loop and
// advance to the next cursor.
if (rv != NS_ERROR_RDF_CURSOR_EMPTY)
return rv;
break;
}
// Even if the current cursor has more elements, we still
// need to check that the current element isn't masked by
// the "main" data source.
// See if data source zero has the negation
// XXX rvg --- this needs to be fixed so that we look at all the prior
// data sources for negations
PRBool hasNegation;
if (NS_FAILED(rv = IsCurrentNegatedBy(mDataSource0,
&hasNegation)))
return rv;
// if not, we're done
if (! hasNegation)
return NS_OK;
// Otherwise, we found the negation in data source
// zero. Gotta keep lookin'...
} while (1);
NS_RELEASE(mCurrentCursor);
NS_RELEASE(mDataSources[mNextDataSource]);
++mNextDataSource;
}
// if we get here, there aren't any elements left.
return NS_ERROR_UNEXPECTED;
}
////////////////////////////////////////////////////////////////////////
// DBAssertionCursor
//
// An assertion cursor implementation for the db.
//
class DBGetTargetsCursor : public nsIRDFAssertionCursor
{
private:
nsIRDFDataBase* mDataBase
nsIRDFResource* mSource;
nsIRDFResource* mLabel;
nsIRDFNode* mTarget;
PRInt32 mCount;
PRBool mTruthValue;
nsIRDFAssertionCursor* mCurrentCursor;
public:
DBGetTargetsCursor(nsIRDFDataBase* db,
nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv);
virtual ~DBGetTargetsCursor();
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIRDFAssertionCursor interface
NS_IMETHOD Advance(void);
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource);
NS_IMETHOD GetSubject(nsIRDFResource** aResource);
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate);
NS_IMETHOD GetObject(nsIRDFNode** aObject);
NS_IMETHOD GetTruthValue(PRBool* aTruthValue);
NS_IMETHOD GetValue(nsIRDFNode** aValue);
};
DBGetTargetsCursor::DBGetTargetsCursor (nsIRDFDataBase* db,
nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv)
: mSource(source),
mProperty(property),
mTruthValue(tv)
{
NS_IF_ADDREF(mSource);
NS_IF_ADDREF(mProperty);
}
DBGetTargetsCursor::~DBGetTargetsCursor(void)
{
NS_IF_RELEASE(mProperty);
NS_IF_RELEASE(mSource);
}
NS_IMETHODIMP_(nsresult)
DBGetTargetsCursor::QueryInterface(REFNSIID iid, void** result) {
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIRDFAssertionCursorIID) ||
iid.Equals(kIRDFCursorIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFAssertionCursor*, this);
/* AddRef(); // not necessary */
return NS_OK;
}
return NS_NOINTERFACE;
}
nsresult
DBGetTargetsCursor::GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result)
{
return ds->GetTargets(mSource, mProperty, mTruthValue,
(nsIRDFAssertionCursor**) result);
}
nsresult
DBGetTargetsCursor::IsCurrentNegatedBy(nsIRDFDataSource* ds0,
PRBool* result)
{
nsresult rv;
// No need to QueryInterface() b/c this is a closed system.
nsIRDFAssertionCursor* c =
(nsIRDFAssertionCursor*) GetCurrentCursor();
PRBool tv;
if (NS_FAILED(rv = c->GetTruthValue(&tv)))
return rv;
nsIRDFNode* object;
if (NS_FAILED(rv = c->GetObject(&object)))
return rv;
rv = ds0->HasAssertion(mSource, mProperty, object, !tv, result);
NS_RELEASE(object);
return rv;
}
NS_IMETHODIMP
DBGetTargetsCursor::Advance(void)
{
return AdvanceImpl();
}
NS_IMETHODIMP
DBGetTargetsCursor::GetDataSource(nsIRDFDataSource** aDataSource)
{
nsIRDFAssertionCursor* cursor =
(nsIRDFAssertionCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetDataSource(aDataSource);
}
NS_IMETHODIMP
DBGetTargetsCursor::GetSubject(nsIRDFResource** aResource)
{
nsIRDFAssertionCursor* cursor =
(nsIRDFAssertionCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetSubject(aResource);
}
NS_IMETHODIMP
DBGetTargetsCursor::GetPredicate(nsIRDFResource** aPredicate)
{
nsIRDFAssertionCursor* cursor =
(nsIRDFAssertionCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetPredicate(aPredicate);
}
NS_IMETHODIMP
DBGetTargetsCursor::GetObject(nsIRDFNode** aObject)
{
nsIRDFAssertionCursor* cursor =
(nsIRDFAssertionCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetObject(aObject);
}
NS_IMETHODIMP
DBGetTargetsCursor::GetTruthValue(PRBool* aTruthValue)
{
nsIRDFAssertionCursor* cursor =
(nsIRDFAssertionCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetTruthValue(aTruthValue);
}
////////////////////////////////////////////////////////////////////////
// SimpleDBArcsOutCursorImpl
class SimpleDBArcsOutCursorImpl : public MultiCursor,
public nsIRDFArcsOutCursor
{
private:
nsIRDFResource* mSource;
public:
SimpleDBArcsOutCursorImpl(nsVoidArray& dataSources, nsIRDFResource* source);
virtual ~SimpleDBArcsOutCursorImpl();
// MultiCursor protocol methods
virtual nsresult
GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result);
virtual nsresult
IsCurrentNegatedBy(nsIRDFDataSource* ds0,
PRBool* result);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIRDFArcsOutCursor interface
NS_IMETHOD Advance(void);
NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource);
NS_IMETHOD GetSubject(nsIRDFResource** aSubject);
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate);
NS_IMETHOD GetTruthValue(PRBool* aTruthValue);
};
SimpleDBArcsOutCursorImpl::SimpleDBArcsOutCursorImpl(nsVoidArray& dataSources,
nsIRDFResource* source)
: MultiCursor(dataSources),
mSource(source)
{
NS_IF_ADDREF(mSource);
}
SimpleDBArcsOutCursorImpl::~SimpleDBArcsOutCursorImpl(void)
{
NS_IF_RELEASE(mSource);
}
nsresult
SimpleDBArcsOutCursorImpl::GetCursor(nsIRDFDataSource* ds, nsIRDFCursor** result)
{
return ds->ArcLabelsOut(mSource, (nsIRDFArcsOutCursor**) result);
}
nsresult
SimpleDBArcsOutCursorImpl::IsCurrentNegatedBy(nsIRDFDataSource* ds0,
PRBool* result)
{
*result = PR_FALSE; // XXX always?
return NS_OK;
}
NS_IMPL_ADDREF(SimpleDBArcsOutCursorImpl);
NS_IMPL_RELEASE(SimpleDBArcsOutCursorImpl);
NS_IMETHODIMP_(nsresult)
SimpleDBArcsOutCursorImpl::QueryInterface(REFNSIID iid, void** result) {
if (! result)
return NS_ERROR_NULL_POINTER;
if (iid.Equals(kIRDFAssertionCursorIID) ||
iid.Equals(kIRDFCursorIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFArcsOutCursor*, this);
/* AddRef(); // not necessary */
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
SimpleDBArcsOutCursorImpl::Advance(void)
{
return AdvanceImpl();
}
NS_IMETHODIMP
SimpleDBArcsOutCursorImpl::GetDataSource(nsIRDFDataSource** aDataSource)
{
nsIRDFArcsOutCursor* cursor =
(nsIRDFArcsOutCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetDataSource(aDataSource);
}
NS_IMETHODIMP
SimpleDBArcsOutCursorImpl::GetSubject(nsIRDFResource** aSubject)
{
nsIRDFArcsOutCursor* cursor =
(nsIRDFArcsOutCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetSubject(aSubject);
}
NS_IMETHODIMP
SimpleDBArcsOutCursorImpl::GetPredicate(nsIRDFResource** aPredicate)
{
nsIRDFArcsOutCursor* cursor =
(nsIRDFArcsOutCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetPredicate(aPredicate);
}
NS_IMETHODIMP
SimpleDBArcsOutCursorImpl::GetTruthValue(PRBool* aTruthValue)
{
nsIRDFArcsOutCursor* cursor =
(nsIRDFArcsOutCursor*) GetCurrentCursor();
if (! cursor)
return NS_ERROR_UNEXPECTED;
return cursor->GetTruthValue(aTruthValue);
}
////////////////////////////////////////////////////////////////////////
// SimpleDataBaseImpl
// XXX rvg --- shouldn't this take a char** argument indicating the data sources
// we want to aggregate?
class SimpleDataBaseImpl : public nsIRDFDataBase {
protected:
nsVoidArray mDataSources;
virtual ~SimpleDataBaseImpl(void);
public:
SimpleDataBaseImpl(void);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIRDFDataSource interface
NS_IMETHOD Init(const char* uri);
NS_IMETHOD GetSource(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFResource** source);
NS_IMETHOD GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFAssertionCursor** sources);
NS_IMETHOD GetTarget(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFNode** target);
NS_IMETHOD GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFAssertionCursor** targets);
NS_IMETHOD Assert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv);
NS_IMETHOD Unassert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target);
NS_IMETHOD HasAssertion(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
PRBool* hasAssertion);
NS_IMETHOD AddObserver(nsIRDFObserver* n);
NS_IMETHOD RemoveObserver(nsIRDFObserver* n);
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
nsIRDFArcsInCursor** labels);
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
nsIRDFArcsOutCursor** labels);
NS_IMETHOD Flush();
// nsIRDFDataBase interface
NS_IMETHOD AddDataSource(nsIRDFDataSource* source);
NS_IMETHOD RemoveDataSource(nsIRDFDataSource* source);
};
////////////////////////////////////////////////////////////////////////
SimpleDataBaseImpl::SimpleDataBaseImpl(void)
{
NS_INIT_REFCNT();
}
SimpleDataBaseImpl::~SimpleDataBaseImpl(void)
{
for (PRInt32 i = mDataSources.Count() - 1; i >= 0; --i) {
nsIRDFDataSource* ds = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[i]);
NS_IF_RELEASE(ds);
}
}
////////////////////////////////////////////////////////////////////////
// nsISupports interface
NS_IMPL_ADDREF(SimpleDataBaseImpl);
NS_IMPL_RELEASE(SimpleDataBaseImpl);
NS_IMETHODIMP
SimpleDataBaseImpl::QueryInterface(REFNSIID iid, void** result)
{
if (! result)
return NS_ERROR_NULL_POINTER;
*result = nsnull;
if (iid.Equals(kIRDFDataBaseIID) ||
iid.Equals(kIRDFDataSourceIID) ||
iid.Equals(kISupportsIID)) {
*result = NS_STATIC_CAST(nsIRDFDataBase*, this);
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
////////////////////////////////////////////////////////////////////////
// nsIRDFDataSource interface
NS_IMETHODIMP
SimpleDataBaseImpl::Init(const char* uri)
{
PR_ASSERT(0);
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
SimpleDataBaseImpl::GetSource(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFResource** source)
{
PRInt32 count = mDataSources.Count();
for (PRInt32 i = 0; i < count; ++i) {
nsIRDFDataSource* ds = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[i]);
if (NS_FAILED(ds->GetSource(property, target, tv, source)))
continue;
// okay, found it. make sure we don't have the opposite
// asserted in the "local" data source
nsIRDFDataSource* ds0 = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[0]);
nsIRDFResource* tmp;
if (NS_FAILED(ds->GetSource(property, target, !tv, &tmp)))
return NS_OK;
NS_RELEASE(tmp);
NS_RELEASE(*source);
return NS_ERROR_FAILURE;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
SimpleDataBaseImpl::GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFAssertionCursor** sources)
{
PR_ASSERT(0);
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
SimpleDataBaseImpl::GetTarget(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFNode** target)
{
PRInt32 count = mDataSources.Count();
for (PRInt32 i = 0; i < count; ++i) {
nsIRDFDataSource* ds = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[i]);
if (NS_FAILED(ds->GetTarget(source, property, tv, target)))
continue;
// okay, found it. make sure we don't have the opposite
// asserted in the "local" data source
nsIRDFDataSource* ds0 = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[0]);
nsIRDFNode* tmp;
if (NS_FAILED(ds0->GetTarget(source, property, !tv, &tmp)))
return NS_OK;
NS_RELEASE(tmp);
NS_RELEASE(*target);
return NS_ERROR_FAILURE;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
SimpleDataBaseImpl::GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFAssertionCursor** targets)
{
if (! targets)
return NS_ERROR_NULL_POINTER;
nsIRDFAssertionCursor* result;
result = new DBGetTargetsCursor(mDataSources, source, property, tv);
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(result);
*targets = result;
return NS_OK;
}
NS_IMETHODIMP
SimpleDataBaseImpl::Assert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv)
{
nsresult rv;
// First see if we just need to remove a negative assertion from ds0. (Sigh)
nsIRDFDataSource* ds0 = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[0]);
PRBool ds0HasNegation;
if (NS_FAILED(rv = ds0->HasAssertion(source, property, target, !tv, &ds0HasNegation)))
return rv;
if (ds0HasNegation) {
if (NS_FAILED(rv = ds0->Unassert(source, property, target)))
return rv;
}
// Now, see if the assertion has been "unmasked"
PRBool isAlreadyAsserted;
if (NS_FAILED(rv = HasAssertion(source, property, target, tv, &isAlreadyAsserted)))
return rv;
if (isAlreadyAsserted)
return NS_OK;
// If not, iterate from the "remote-est" data source to the
// "local-est", trying to make the assertion.
for (PRInt32 i = mDataSources.Count() - 1; i >= 0; --i) {
nsIRDFDataSource* ds = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[i]);
if (NS_SUCCEEDED(ds->Assert(source, property, target, tv)))
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
SimpleDataBaseImpl::Unassert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target)
{
// XXX I have no idea what this is trying to do. I'm just going to
// copy Guha's logic and punt.
// xxx rvg - first need to check whether the data source does have the
// assertion. Only then do you try to unassert it.
nsresult rv;
PRInt32 count = mDataSources.Count();
for (PRInt32 i = 0; i < count; ++i) {
nsIRDFDataSource* ds = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[i]);
if (NS_FAILED(rv = ds->Unassert(source, property, target)))
break;
}
if (NS_FAILED(rv)) {
nsIRDFDataSource* ds0 = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[0]);
rv = ds0->Assert(source, property, target, PR_FALSE);
}
return rv;
}
NS_IMETHODIMP
SimpleDataBaseImpl::HasAssertion(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
PRBool* hasAssertion)
{
nsresult rv;
// First check to see if ds0 has the negation...
nsIRDFDataSource* ds0 = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[0]);
PRBool ds0HasNegation;
if (NS_FAILED(rv = ds0->HasAssertion(source, property, target, !tv, &ds0HasNegation)))
return rv;
if (ds0HasNegation) {
*hasAssertion = PR_FALSE;
return NS_OK;
}
// Otherwise, look through all the data sources to see if anyone
// has the positive...
PRInt32 count = mDataSources.Count();
for (PRInt32 i = 0; i < count; ++i) {
nsIRDFDataSource* ds = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[i]);
if (NS_FAILED(rv = ds->HasAssertion(source, property, target, tv, hasAssertion)))
return rv;
if (hasAssertion)
return NS_OK;
}
// If we get here, nobody had the assertion at all
return NS_OK;
}
NS_IMETHODIMP
SimpleDataBaseImpl::AddObserver(nsIRDFObserver* n)
{
PR_ASSERT(0);
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
SimpleDataBaseImpl::RemoveObserver(nsIRDFObserver* n)
{
PR_ASSERT(0);
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
SimpleDataBaseImpl::ArcLabelsIn(nsIRDFNode* node,
nsIRDFArcsInCursor** labels)
{
PR_ASSERT(0);
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
SimpleDataBaseImpl::ArcLabelsOut(nsIRDFResource* source,
nsIRDFArcsOutCursor** labels)
{
if (! labels)
return NS_ERROR_NULL_POINTER;
nsIRDFArcsOutCursor* result = new SimpleDBArcsOutCursorImpl(mDataSources, source);
if (! result)
return NS_ERROR_NULL_POINTER;
NS_ADDREF(result);
*labels = result;
return NS_OK;
}
NS_IMETHODIMP
SimpleDataBaseImpl::Flush()
{
for (PRInt32 i = mDataSources.Count() - 1; i >= 0; --i) {
nsIRDFDataSource* ds = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[i]);
ds->Flush();
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// nsIRDFDataBase methods
// XXX rvg We should make this take an additional argument specifying where
// in the sequence of data sources (of the db), the new data source should
// fit in. Right now, the new datasource gets stuck at the end.
NS_IMETHODIMP
SimpleDataBaseImpl::AddDataSource(nsIRDFDataSource* source)
{
if (! source)
return NS_ERROR_NULL_POINTER;
mDataSources.InsertElementAt(source, 0);
NS_ADDREF(source);
return NS_OK;
}
NS_IMETHODIMP
SimpleDataBaseImpl::RemoveDataSource(nsIRDFDataSource* source)
{
if (! source)
return NS_ERROR_NULL_POINTER;
if (mDataSources.IndexOf(source) >= 0) {
mDataSources.RemoveElement(source);
NS_RELEASE(source);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsresult
NS_NewRDFSimpleDataBase(nsIRDFDataBase** result)
{
SimpleDataBaseImpl* db = new SimpleDataBaseImpl();
if (! db)
return NS_ERROR_OUT_OF_MEMORY;
*result = db;
NS_ADDREF(*result);
return NS_OK;
}

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

@ -60,7 +60,7 @@ public:
PRBool mTv;
Assertion* mNext;
Assertion* mInvNext;
}
};
////////////////////////////////////////////////////////////////////////
@ -205,6 +205,7 @@ public:
NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate);
NS_IMETHOD GetObject(nsIRDFNode** aObject);
NS_IMETHOD GetTruthValue(PRBool* aTruthValue);
NS_IMETHOD GetValue(nsIRDFNode** aValue);
};
////////////////////////////////////////////////////////////////////////
@ -229,11 +230,8 @@ InMemoryAssertionCursor::InMemoryAssertionCursor (InMemoryDataSource* ds,
mTarget = u;
mNextAssertion = mDataSource->getArg2(u);
} else {
mSource = u;
mSource = (nsIRDFResource*) u;
mNextAssertion = mDataSource->getArg1(mSource);
// Dont need this ...
// if (NS_SUCCEEDED(u->QueryInterface(kIRDFResourceIID, (void**) &mSource)))
// mNextAssertion = mDataSource->getArg1(mSource);
}
}
@ -247,10 +245,6 @@ NS_IMPL_ISUPPORTS(InMemoryAssertionCursor, kIRDFAssertionCursorIID);
NS_IMETHODIMP
InMemoryAssertionCursor::Advance(void)
{
// XXX I don't think that the semantics of this are quite right:
// specifically, I think that the initial Advance() will skip the
// first element...
// Guha --- I am pretty sure it won't
nsresult rv;
NS_IF_RELEASE(mValue);
@ -265,7 +259,7 @@ InMemoryAssertionCursor::Advance(void)
mValue = mNextAssertion->mSource;
NS_ADDREF(mValue);
} else {
mValue = mNextAssertion->target;
mValue = mNextAssertion->mTarget;
NS_ADDREF(mValue);
}
return NS_OK;
@ -277,6 +271,17 @@ InMemoryAssertionCursor::Advance(void)
return NS_ERROR_RDF_CURSOR_EMPTY;
}
NS_IMETHODIMP
InMemoryAssertionCursor::GetValue (nsIRDFNode** aValue) {
if (! aValue)
return NS_ERROR_NULL_POINTER;
NS_ADDREF(mValue);
*aValue = mValue;
return NS_OK;
}
NS_IMETHODIMP
InMemoryAssertionCursor::GetDataSource(nsIRDFDataSource** aDataSource)
{
@ -477,7 +482,7 @@ InMemoryDataSource::GetTarget(nsIRDFResource* source, nsIRDFResource* property,
if (as->mTv != tv)
continue;
*target = as->target;
*target = as->mTarget;
return NS_OK;
}
@ -500,7 +505,7 @@ InMemoryDataSource::HasAssertion(nsIRDFResource* source, nsIRDFResource* propert
if (! eq)
continue;
if (NS_FAILED(rv = target->EqualsNode(as->target, &eq)))
if (NS_FAILED(rv = target->EqualsNode(as->mTarget, &eq)))
return rv;
if (! eq)
@ -523,7 +528,7 @@ NS_IMETHODIMP
InMemoryDataSource::GetSources(nsIRDFResource* property, nsIRDFNode* target,
PRBool tv, nsIRDFAssertionCursor** sources)
{
*sources = new InMemoryAssertionCursor (this, target, property, tv, PR_TRUE);
*sources = new InMemoryAssertionCursor(this, target, property, tv, PR_TRUE);
return NS_OK;
}
@ -532,7 +537,7 @@ InMemoryDataSource::GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv, nsIRDFAssertionCursor** targets)
{
*targets = new InMemoryAssertionCursor (this, source, property, tv, PR_FALSE);
*targets = new InMemoryAssertionCursor(this, source, property, tv, PR_FALSE);
return NS_OK;
}
@ -555,7 +560,7 @@ InMemoryDataSource::Assert(nsIRDFResource* source, nsIRDFResource* property,
return rv;
if (eq) {
if (NS_FAILED(rv = target->EqualsNode(next->target, &eq)))
if (NS_FAILED(rv = target->EqualsNode(next->mTarget, &eq)))
return rv;
if (eq) {
@ -581,7 +586,7 @@ InMemoryDataSource::Assert(nsIRDFResource* source, nsIRDFResource* property,
as->mProperty = property;
NS_ADDREF(target);
as->target = target;
as->mTarget = target;
as->mTv = tv;
@ -632,7 +637,7 @@ InMemoryDataSource::Unassert(nsIRDFResource* source,
return rv;
if (eq) {
if (NS_FAILED(rv = target->EqualsNode(next->target, &eq)))
if (NS_FAILED(rv = target->EqualsNode(next->mTarget, &eq)))
return rv;
if (eq) {