[isidorus-cvs] r204 - branches/new-datamodel/src/model trunk/src/model
Lukas Giessmann
lgiessmann at common-lisp.net
Wed Feb 24 16:04:47 UTC 2010
Author: lgiessmann
Date: Wed Feb 24 11:04:46 2010
New Revision: 204
Log:
new-datamodel: added the functions get-item-by-item-identifier, get-item-by-psi, get-item-by-locator; fixed a bug in the function get-item-by-id -> ticket #65
Modified:
branches/new-datamodel/src/model/datamodel.lisp
trunk/src/model/datamodel.lisp
Modified: branches/new-datamodel/src/model/datamodel.lisp
==============================================================================
--- branches/new-datamodel/src/model/datamodel.lisp (original)
+++ branches/new-datamodel/src/model/datamodel.lisp Wed Feb 24 11:04:46 2010
@@ -10,6 +10,8 @@
(defpackage :datamodel
(:use :cl :elephant :constants)
(:nicknames :d)
+ (:import-from :exceptions
+ duplicate-identifier-error)
(:export ;;classes
:TopicMapC
:AssociationC
@@ -79,6 +81,11 @@
:in-topicmaps
:delete-construct
:get-revision
+ :get-item-by-id
+ :get-item-by-psi
+ :get-item-by-item-identnfier
+ :get-item-by-locator
+ :string-integer-p
;;globals
:*TM-REVISION*
@@ -87,6 +94,12 @@
(in-package :datamodel)
+;;TODO: fix this line (make-instance 'TopicC :from-oid (subseq topic-id 1)))))
+;; in get-item-by-id
+;;TODO: implement get-item-by-id(TopicC) + unit-tests
+;;TODO: implement get-item-by-psi(TopicC) + unit-tests
+;;TODO: implement get-item-by-locator(TopicC) + unit-tests
+;;TODO: implement get-item-by-item-identifier(ReifiableConstructC) + unit-tests
;;TODO: replace add-to-version-history in VersionedAssociationC with a pseudo
;; initarg in make-construct
;;TODO: implement a macro "with-merge-construct" that merges constructs
@@ -609,6 +622,13 @@
(get-universal-time))
+(defun string-integer-p (integer-as-string)
+ "Returns t if the passed string can be parsed to an integer."
+ (handler-case (when (parse-integer integer-as-string)
+ t)
+ (condition () nil)))
+
+
;;; generic functions/accessors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; VersionInfocC
(defmethod delete-construct :before ((version-info VersionInfoC))
@@ -1061,6 +1081,96 @@
(filter-slot-value-by-revision topic 'in-topicmaps :start-revision revision))
+(defun get-item-by-id (topic-id &key (xtm-id *CURRENT-XTM*) (revision 0) (error-if-nil nil))
+ "Gets a topic by its id, assuming an xtm-id. If xtm-id is empty, the current TM
+ is chosen. If xtm-id is nil, choose the global TM with its internal ID, if
+ applicable in the correct revision. If revison is provided, then the code checks
+ if the topic already existed in this revision and returns nil otherwise.
+ If no item meeting the constraints was found, then the return value is either
+ NIL or an error is thrown, depending on error-if-nil."
+ (declare (string topic-id) (integer revision) (string xtm-id))
+ (let ((result
+ (if xtm-id
+ (let ((possible-top-ids
+ (delete-if-not
+ #'(lambda(top-id)
+ (and (string= (xtm-id top-id) xtm-id)
+ (string= (uri top-id) topic-id)))
+ ;fixes a bug in get-instances-by-value that does a
+ ;case-insensitive comparision
+ (elephant:get-instances-by-value
+ 'TopicIdentificationC
+ 'uri
+ topic-id))))
+ (when (and possible-top-ids
+ (identified-construct (first possible-top-ids) :revision revision))
+ (unless (= (length possible-top-ids) 1)
+ (error (make-condition 'duplicate-identifier-error
+ :message (format nil "(length possible-items ~a) for id ~a and xtm-id ~a > 1"
+ possible-top-ids topic-id xtm-id)
+ :uri topic-id)))
+ (identified-construct (first possible-top-ids)
+ :revision revision)
+ ;no revision need not to be chaecked, since the revision
+ ;is implicitely checked by the function identified-construct
+ ))
+ (when (and (> (length topic-id) 0)
+ (eql (elt 0 topic-id) #\t)
+ (string-integer-p (subseq topic-id 1)))
+ (elephant::controller-recreate-instance elephant::*store-controller* (subseq topic-id 1))))))
+ (if (and error-if-nil (not result))
+ (error "No such item (id: ~a, tm: ~a, rev: ~a)" topic-id xtm-id revision)
+ result)))
+
+
+(defun get-item-by-identifier (uri &key (revision 0)
+ (identifier-type-symbol 'PersistentIdC)
+ (error-if-nil nil))
+ "Returns the construct that is bound to the given identifier-uri."
+ (declare (string uri) (integer revision) (symbol identifier-type-symbol))
+ (let ((result
+ (let ((possible-ids
+ (delete-if-not
+ #'(lambda(id)
+ (string= (uri id) uri))
+ (get-instances-by-class identifier-type-symbol))))
+ (when (and possible-ids
+ (identified-construct (first possible-ids) :revision revision))
+ (unless (= (length possible-ids) 1)
+ (error (make-condition 'duplicate-identifier-error
+ :message (format nil "(length possible-items ~a) for id ~a"
+ possible-ids uri)
+ :uri uri)))
+ (identified-construct (first possible-ids)
+ :revision revision)))))
+ ;no revision need not to be checked, since the revision
+ ;is implicitely checked by the function identified-construct
+ (if result
+ result
+ (when error-if-nil
+ (error "No such item is bound to the given identifier uri.")))))
+
+
+(defun get-item-by-item-identifier (uri &key (revision 0) (error-if-nil nil))
+ "Returns a ReifiableConstructC that is bound to the identifier-uri."
+ (get-item-by-identifier uri :revision revision
+ :identifier-type-symbol 'ItemIdentifierC
+ :error-if-nil error-if-nil))
+
+
+(defun get-item-by-psi (uri &key (revision 0) (error-if-nil nil))
+ "Returns a TopicC that is bound to the identifier-uri."
+ (get-item-by-identifier uri :revision revision
+ :identifier-type-symbol 'PersistentIdC
+ :error-if-nil error-if-nil))
+
+
+(defun get-item-by-locator (uri &key (revision 0) (error-if-nil nil))
+ "Returns a TopicC that is bound to the identifier-uri."
+ (get-item-by-identifier uri :revision revision
+ :identifier-type-symbol 'SubjectLocatorC
+ :error-if-nil error-if-nil))
+
;;; NameC
(defgeneric variants (construct &key revision)
Modified: trunk/src/model/datamodel.lisp
==============================================================================
--- trunk/src/model/datamodel.lisp (original)
+++ trunk/src/model/datamodel.lisp Wed Feb 24 11:04:46 2010
@@ -1360,7 +1360,7 @@
(if (= revision 0)
found-topic
(find-item-by-revision found-topic revision)))))
- (make-instance 'TopicC :from-oid (subseq topicid 1)))))
+ (elephant::controller-recreate-instance elephant:*store-controller* (subseq topicid 1)))))
(if (and error-if-nil (not result))
(error (format nil "no such item (id: ~a, tm: ~a, rev: ~a)" topicid xtm-id revision))
result)))
More information about the Isidorus-cvs
mailing list