Coverage report: /development/source/library/org/datagraph/spocq-shard/src/store/rdfcache/metadata-mysql2rdf.lisp
| Kind | Covered | All | % |
| expression | 298 | 1246 | 23.9 |
| branch | 17 | 134 | 12.7 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;; -*- Mode: lisp; Syntax: ansi-common-lisp; Base: 10; Package: org.datagraph.spocq.implementation; -*-
4
(in-package :org.datagraph.spocq.implementation)
6
(:documentation "metadata synchronization"
7
"synchronize metadata from mysql db to rdf repositories by gathering everything
8
on each account and splitting the user-modifyable from the system-controlled
9
properties, placing the former in the account specific repository '<account>/system'
10
and the latter system-wide repository 'system/system'.
12
the transport process is performed via a shell script.
13
a core-based versionis in /opt/rails/script/export-metadata.sh
14
the executable-based script is in /srv/dydra/bin/spocq-mysql-to-rdf
17
;;; (load #p"LIBRARY:org;datagraph;spocq;src;core;package.lisp")
18
;;; (load #p"LIBRARY:org;datagraph;spocq;src;store;accounts.lisp")
21
(defparameter *account-column-names*
22
(split-string #+(or) ;; 2015-08-15: admin disappeared
23
"id, email, encrypted_password, authentication_token, remember_created_at,
24
reset_password_token, name, fullname, admin, cached_slug, request_timeout_limit, default_repository_prefixes,
25
homepage, blog, company, location, phone, skype_id, jabber_id, region, host"
26
"id, email, encrypted_password, authentication_token, remember_created_at,
27
reset_password_token, name, fullname, cached_slug, request_timeout_limit, default_repository_prefixes,
28
homepage, blog, company, location, phone, skype_id, jabber_id, region, host"
29
#(#\, #\space #\newline #\return)))
31
(defparameter *repository-column-names*
32
(split-string #+(or) ;; 2015-08-15: the licenses table has disappeared, as have triple_count, byte_size, latest_rdfcache_revision
33
"id, uuid, name, account_id, license_id, homepage, summary,
34
description, cached_slug, triple_count, byte_size, latest_rdfcache_revision, privacy_setting,
35
permissable_ip_addresses, default_repository_prefixes"
36
"id, uuid, name, account_id, homepage, summary,
37
description, cached_slug, privacy_setting,
38
permissable_ip_addresses, default_repository_prefixes"
39
#(#\, #\space #\newline #\return)))
43
(defun mysql-account-list (&key (mysql-host *mysql-host*)
44
(mysql-database *mysql-database*))
45
(let* ((command (format nil "mysql -h ~a -u root ~a -BNe \"SELECT cached_slug FROM accounts;\""
46
mysql-host mysql-database))
48
(sb-ext:run-program "/bin/sh" (list "-c" command)
49
:input nil :output :stream
51
(loop for line = (read-line (sb-ext:process-output process) nil)
54
finally (close (sb-ext:process-output process)))))
56
(defun mysql-account-metadata-records (account-slug &key (mysql-host *mysql-host*)
57
(mysql-database *mysql-database*)
58
(column-names *account-column-names*))
59
(let* ((column-keys (loop for name in column-names
60
collect (intern (string-upcase name) :keyword)))
61
(account-command (format nil "mysql -h ~a -u root ~a -BNe \"SELECT ~{~a~^, ~} FROM accounts~@[ WHERE accounts.cached_slug ='~a'~];\""
62
mysql-host mysql-database column-names account-slug))
64
(sb-ext:run-program "/bin/sh" (list "-c" account-command)
65
:input nil :output :stream)))
66
(loop for line = (read-line (sb-ext:process-output process) nil)
68
collect (loop for value in (split-string line #(#\tab) :strict t)
69
for key in column-keys
70
unless (string-equal value "null")
71
append (list key value))
72
finally (close (sb-ext:process-output process)))))
74
(defun mysql-repository-metadata-records (account-cached-slug repository-name &key (mysql-host *mysql-host*)
75
(mysql-database *mysql-database*)
76
(column-names *repository-column-names*))
77
(let* ((column-keys (list* :account_name :account_cached_slug
78
#+(or) ;; 2015-08-15: the licenses table has disappeared
80
(loop for name in column-names
81
collect (intern (string-upcase name) :keyword))))
82
(account-command (format nil
83
#+(or) ;; 2015-08-15: the licenses table has disappeared
84
"mysql -h ~a -u root ~a -BNe \"SELECT a.name, a.cached_slug, l.url, ~{r.~a~^, ~} FROM accounts a, repositories r
85
left join licenses l on r.license_id = l.id
86
where a.cached_slug = '~a' and ~@[r.cached_slug = '~a' and ~]r.account_id = a.id ;\""
87
"mysql -h ~a -u root ~a -BNe \"SELECT a.name, a.cached_slug, ~{r.~a~^, ~} FROM accounts a, repositories r
88
where a.cached_slug = '~a' and ~@[r.cached_slug = '~a' and ~]r.account_id = a.id ;\""
89
mysql-host mysql-database column-names
90
account-cached-slug repository-name))
92
(sb-ext:run-program "/bin/sh" (list "-c" account-command)
93
:input nil :output :stream
95
(loop for line = (read-line (sb-ext:process-output process) nil)
97
collect (loop for value in (split-string line #(#\tab) :strict t)
98
for key in column-keys
99
unless (string-equal value "null")
100
append (list key value))
101
finally (close (sb-ext:process-output process)))))
103
(defun mysql-repository-view-records (account-cached-slug repository-cached-slug &key (mysql-host *mysql-host*)
104
(mysql-database *mysql-database*))
105
(let* ((column-keys (list :account_cached_slug :repository_cached_slug :name :cached_slug :query_text))
106
(command (format nil "mysql -h ~a -u root ~a -BNe \"SELECT a.cached_slug, r.cached_slug, q.name, q.cached_slug, q.query_text
107
FROM accounts a, repositories r, queries q
108
WHERE ~@[a.cached_slug = '~a' and ~]~@[r.cached_slug = '~a' and ~]r.account_id = a.id and q.account_id = a.id and q.repository_id = r.id;\""
109
mysql-host mysql-database
110
account-cached-slug repository-cached-slug))
112
(sb-ext:run-program "/bin/sh" (list "-c" command)
113
:input nil :output :stream
115
(loop for line = (read-line (sb-ext:process-output process) nil)
117
collect (loop for value in (split-string line #(#\tab) :strict t)
118
for key in column-keys
119
unless (string-equal value "null")
120
append (list key (case key
121
((:summary :query_text) (unescape-mysql-string value))
123
finally (close (sb-ext:process-output process)))))
124
;;; (mysql-repository-view-records "james" "test")
125
;;; (mysql-repository-view-records "james" "foaf")
126
;;; (mysql-repository-view-records "james" nil)
127
;;; (mysql-repository-view-records nil nil)
129
(defun mysql-collaboration-records (owner-account-name repository-name &key (mysql-host *mysql-host*)
130
(mysql-database *mysql-database*))
131
(let* ((column-keys '(:account :repository :collaborator :read :write))
132
(collaboration-command (format nil
133
"mysql -h ~a -u root ~a -BNe \"SELECT a.cached_slug as account_name, r.cached_slug as repository_name, ac.cached_slug as collaborator_name, c.read, c.write
134
FROM accounts ac, accounts a, repositories r, collaborations c
135
WHERE a.cached_slug = '~a' and r.cached_slug = '~a' and r.account_id = a.id and c.repository_id = r.id and ac.id = c.account_id;\""
136
mysql-host mysql-database
137
owner-account-name repository-name))
139
(sb-ext:run-program "/bin/sh" (list "-c" collaboration-command)
140
:input nil :output :stream
142
(loop for line = (read-line (sb-ext:process-output process) nil)
144
collect (loop for value in (split-string line #(#\tab) :strict t)
145
for key in column-keys
146
unless (string-equal value "null")
147
append (list key value))
148
finally (close (sb-ext:process-output process)))))
150
;;; (mysql-account-list)
151
;;; (mysql-account-metadata-records "jhacker")
152
;;; (mysql-repository-metadata-records "jhacker" "insert-test") "tbl-extended"
153
;;; (mysql-collaboration-records "nxp" "plm")
155
(defun mysql-account-metadata-statements (account-slug &rest args)
156
"Transport the account metadata into the global and account 'system' repositores.
157
Identifying information is placed in the global store because
158
- it should be readily searchable, that is, without federation
159
- aspects of it a system-controlled rather than user controlled.
160
Authentication, 'social', and processing config properties are under user control and,
161
as such, placed in the account repository."
163
(let ((account-records (apply #'mysql-account-metadata-records account-slug args)))
164
(loop for account-record in account-records
165
;; 20170131 : do not derive admin from mysql metadata, as it is in a filesystem file
166
append (destructuring-bind (&key id email encrypted_password authentication_token
167
name cached_slug fullname request_timeout_limit default_repository_prefixes
168
homepage blog company location phone skype_id jabber_id region host
169
&allow-other-keys) account-record
170
;; (print (cons :account-record account-record))
171
(unless (equal name cached_slug)
172
(warn "account name: ~s cached_slug: ~s" name cached_slug))
173
(let ((account-uri (compute-account-identifier cached_slug))
174
(sesame-uri (intern-iri (format nil "http://~a/~a" (site-name) cached_slug)))
175
(owner-uri (intern-iri (format nil "http://dydra.com/users/~a" cached_slug)))
176
(first-and-last (split-string fullname #(#\space)))
177
(account-access-node (cons-global-blank-node :prefix "acl"))
178
(account-uuid (intern-uuid (account-uuid cached_slug))))
180
;; identifying information for the account and for the user
181
;; place it in the 'account' graph to facilitate modifications
182
(;; account identity assertions are placed in the <urn:dydra:accounts> graph
183
(spocq.a:|quad| ,account-uri |rdf|:|type| |urn:dydra|:|Account| |urn:dydra|:|accounts|)
184
(spocq.a:|quad| ,account-uri |acl|:|owner| ,owner-uri |urn:dydra|:|accounts|)
186
;; user identity assertions and authentication are placed in the <urn:dydra:users> graph
187
(spocq.a:|quad| ,owner-uri |rdf|:|type| |urn:dydra|:|User| |urn:dydra|:|users|) ;; change to be user-specific
188
;; the sioc schema specifies a literal, but that would be redundant with sioc:name
189
;; and "id" is closer to identifier
190
(spocq.a:|quad| ,owner-uri |sioc|:|id| ,owner-uri |urn:dydra|:|users|)
191
(spocq.a:|quad| ,owner-uri |dc|:|title| ,name |urn:dydra|:|users|)
192
;; the primary owner is used for authentication
193
(spocq.a:|quad| ,owner-uri |urn:dydra|:|encryptedPassword| ,encrypted_password |urn:dydra|:|users|)
194
(spocq.a:|quad| ,owner-uri |urn:dydra|:|accessToken| ,authentication_token |urn:dydra|:|users|)
196
`((spocq.a:|quad| ,owner-uri |urn:dydra|:|host| ,host |urn:dydra|:|users|)))
198
;; retain the internal/external id/name pairing for posterity
199
(spocq.a:|quad| ,account-uri |sioc|:|id| ,account-uri ,account-uri)
200
(spocq.a:|quad| ,account-uri |sioc|:|id| ,id ,account-uri)
201
(spocq.a:|quad| ,account-uri |foaf|:|accountName| ,cached_slug ,account-uri)
202
(spocq.a:|quad| ,account-uri |dc|:|title| ,name ,account-uri)
203
(spocq.a:|quad| ,account-uri |sioc|:|has_owner| ,owner-uri ,account-uri)
204
(spocq.a:|quad| ,account-uri |sioc|:|account_of| ,owner-uri ,account-uri)
205
(spocq.a:|quad| ,account-uri <http://dydra.com/operations#uuid> ,account-uuid ,account-uri)
207
;; owner (agent) profile
208
(spocq.a:|quad| ,owner-uri |foaf|:|mbox| ,email ,owner-uri)
209
,@(when first-and-last
210
(let ((first (first first-and-last))
211
(last (second first-and-last)))
213
`((spocq.a:|quad| ,owner-uri |foaf|:|firstName| ,(first first-and-last) ,owner-uri)))
215
`((spocq.a:|quad| ,owner-uri |foaf|:|familyName| ,(second first-and-last) ,owner-uri))))))
217
`((spocq.a:|quad| ,account-uri |urn:dydra|:|region| ,region ,account-uri)))
222
(,@(compute-initial-account-authorization-graph cached_slug)
223
(spocq.a:|quad| ,account-uri |rdf|:|type| |urn:dydra|:|Account| ,account-uri)
225
(spocq.a:|quad| ,account-access-node |acl|:|accessTo| ,account-uri ,account-uri)
226
(spocq.a:|quad| ,account-uri |sioc|:|id| ,sesame-uri ,account-uri)
227
(spocq.a:|quad| ,account-access-node |acl|:|mode| |acl|:|Read| ,account-uri)
228
(spocq.a:|quad| ,account-access-node |acl|:|mode| |acl|:|Write| ,account-uri)
229
(spocq.a:|quad| ,account-access-node |acl|:|mode| |acl|:|Execute| ,account-uri)
230
(spocq.a:|quad| ,account-access-node |acl|:|agent| ,owner-uri ,account-uri)
232
;; account configuration
233
,@(when default_repository_prefixes
234
(multiple-value-bind (prefixes base)
235
(split-prefixes-setting default_repository_prefixes)
236
(append (when prefixes
237
`((spocq.a:|quad| ,account-uri |urn:dydra|:|prefixes| ,prefixes ,account-uri)))
239
`((spocq.a:|quad| ,account-uri |urn:dydra|:|baseIRI| ,base ,account-uri))))))
240
,@(when request_timeout_limit
241
`((spocq.a:|quad| ,account-uri |urn:dydra|:|requestTimeLimit| ,request_timeout_limit ,account-uri)))
245
`((spocq.a:|quad| ,account-uri |foaf|:|homepage| ,homepage ,account-uri)))
247
`((spocq.a:|quad| ,account-uri |foaf|:|weblog| ,blog ,account-uri)))
249
`((spocq.a:|quad| ,account-uri |foaf|:|workInfoHomepage| ,company ,account-uri)))
251
`((spocq.a:|quad| ,account-uri |urn:dydra|:|location| ,location ,account-uri)))
253
`((spocq.a:|quad| ,account-uri |foaf|:|phone| ,phone ,account-uri)))
255
`((spocq.a:|quad| ,account-uri |foaf|:|skypeID| ,skype_id ,account-uri)))
257
`((spocq.a:|quad| ,account-uri |foaf|:|jabberID| ,jabber_id ,account-uri)))
261
;;; see http://vocab.deri.ie/void
262
(defun mysql-repository-metadata-statements (account-slug repository-slug &rest args)
263
"Transliterate repository metadata from a mysql table to statements in the system and respective account
264
repositories. The system entries are written into the default graph in order to be readily accessible.
265
They identify and classify the repository and specify its ownership and constituency.
266
The account entries are written into a repository-specific graph as the repository id is known
267
when they are retrieved."
269
(let ((repository-records (apply #'mysql-repository-metadata-records account-slug repository-slug args)))
270
(loop for repository-record in repository-records
271
collect (destructuring-bind (&key id name cached_slug account_name account_cached_slug license_url
272
homepage summary description privacy_setting permissible_ip_addresses
273
default_repository_prefixes uuid
274
&allow-other-keys) repository-record
275
(declare (ignore account_name))
276
;;(print (cons :repository-record repository-record))
277
(unless (equal name cached_slug)
278
(warn "repository name: ~s cached_slug: ~s" name cached_slug))
279
(let* ((site-name (site-name))
280
(account-uri (compute-account-identifier account_cached_slug))
281
(owner-uri (intern-iri (format nil "http://~a/users/~a" site-name account_cached_slug)))
282
(repository-uri (compute-repository-identifier account_cached_slug cached_slug))
283
(graphstore-repository-uri (intern-iri (format nil "http://~a/~a/~a" (site-name) account_cached_slug cached_slug)))
284
(metadata-repository-uri (intern-iri (format nil "http://~a/accounts/~a/repositories/~a" (site-name) account_cached_slug cached_slug)))
285
(sesame-repository-uri (intern-iri (format nil "http://~a/~a/repositories/~a" (site-name) account_cached_slug cached_slug)))
286
(ip-access-node (cons-global-blank-node :prefix "acl"))
287
(read-access-node (cons-global-blank-node :prefix "acl"))
288
(store-uuid (repository-uuid (make-repository-id :account-name account_cached_slug
289
:repository-name cached_slug)))
290
(repository-uuid (when store-uuid (intern-uuid store-uuid))))
291
(unless (equalp uuid store-uuid)
292
(warn "repository ~:[not present~;relocated~] in file system: ~a ~a/~a: ~a != ~a"
293
store-uuid id account_cached_slug cached_slug uuid store-uuid))
295
;; identifying information for the repository, with ownership and constituency relations
296
((spocq.a:|quad| ,repository-uri |rdf|:|type| <http://rdfs.org/ns/void#Dataset> ,account-uri)
297
(spocq.a:|quad| ,repository-uri |rdf|:|type| |urn:dydra|:|Repository| ,account-uri)
298
(spocq.a:|quad| ,repository-uri |sioc|:|id| ,id ,account-uri)
299
(spocq.a:|quad| ,repository-uri |sioc|:|id| ,repository-uri ,account-uri)
300
(spocq.a:|quad| ,repository-uri |foaf|:|name| ,cached_slug ,account-uri)
301
(spocq.a:|quad| ,repository-uri |dc|:|title| ,name ,account-uri)
302
(spocq.a:|quad| ,repository-uri |sioc|:|has_owner| ,owner-uri ,account-uri)
303
(spocq.a:|quad| ,repository-uri |sioc|:|has_parent| ,account-uri ,account-uri)
304
(spocq.a:|quad| ,repository-uri |acl|:|owner| ,owner-uri ,account-uri)
305
(spocq.a:|quad| ,repository-uri <http://dydra.com/operations#uuid> ,repository-uuid ,account-uri)
309
((spocq.a:|quad| ,repository-uri |rdf|:|type| |urn:dydra|:|Repository| ,repository-uri)
310
;;; retain the privacy setting for posterity
311
(spocq.a:|quad| ,repository-uri |urn:dydra|:|privacySetting| ,privacy_setting ,repository-uri)
312
;; access control for the repository
313
;; see http://www.w3.org/wiki/WebAccessControl
314
;; first the general access
315
,@(compute-initial-repository-authorization-graph account_cached_slug cached_slug)
316
;; then specific to the permission mode, whereby less restrictive modes permit also the more restrictive
317
,@(cond ((equal privacy_setting "1") ; owner only is in the initial graph above
319
((equal privacy_setting "2") ; owner plus write by ip
320
`((spocq.a:|quad| ,ip-access-node |acl|:|accessTo| ,repository-uri ,repository-uri)
321
(spocq.a:|quad| ,ip-access-node |acl|:|accessTo| ,graphstore-repository-uri ,repository-uri)
322
(spocq.a:|quad| ,ip-access-node |acl|:|accessTo| ,metadata-repository-uri ,repository-uri)
323
(spocq.a:|quad| ,ip-access-node |acl|:|accessTo| ,sesame-repository-uri ,repository-uri)
324
(spocq.a:|quad| ,ip-access-node |acl|:|mode| |acl|:|Read| ,repository-uri)
325
(spocq.a:|quad| ,ip-access-node |acl|:|mode| |acl|:|Write| ,repository-uri)
326
(spocq.a:|quad| ,ip-access-node |acl|:|agent| ,owner-uri ,repository-uri)
327
(spocq.a:|quad| ,ip-access-node |acl|:|agent| |urn:dydra|:|LocatedAgent| ,repository-uri)
328
,@(when (plusp (length permissible_ip_addresses))
329
(loop for address in (split-string permissible_ip_addresses #(#\,))
330
collect `(spocq.a:|quad| ,ip-access-node |sioc|:|ip_address| ,address ,repository-uri)))))
331
((equal privacy_setting "3") ; owner plus read access for authenticated users
332
`((spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,repository-uri ,repository-uri)
333
(spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,graphstore-repository-uri ,repository-uri)
334
(spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,metadata-repository-uri ,repository-uri)
335
(spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,sesame-repository-uri ,repository-uri)
336
(spocq.a:|quad| ,read-access-node |acl|:|mode| |acl|:|Read| ,repository-uri)
337
(spocq.a:|quad| ,read-access-node |acl|:|agent| |urn:dydra|:|User| ,repository-uri)))
338
((equal privacy_setting "4") ; owner plus read by ip or authenticated user
339
`((spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,repository-uri ,repository-uri)
340
(spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,graphstore-repository-uri ,repository-uri)
341
(spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,metadata-repository-uri ,repository-uri)
342
(spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,sesame-repository-uri ,repository-uri)
343
(spocq.a:|quad| ,read-access-node |acl|:|mode| |acl|:|Read| ,repository-uri)
344
(spocq.a:|quad| ,read-access-node |acl|:|agent| |urn:dydra|:|User| ,repository-uri)
345
(spocq.a:|quad| ,ip-access-node |acl|:|agent| |urn:dydra|:|LocatedAgent| ,repository-uri)
346
,@(when (plusp (length permissible_ip_addresses))
347
(loop for address in (split-string permissible_ip_addresses #(#\,))
348
collect `(spocq.a:|quad| ,ip-access-node |sioc|:|ip_address| ,address ,repository-uri)))))
349
((equal privacy_setting "5") ; anonymous read access
350
`((spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,repository-uri ,repository-uri)
351
(spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,graphstore-repository-uri ,repository-uri)
352
(spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,metadata-repository-uri ,repository-uri)
353
(spocq.a:|quad| ,read-access-node |acl|:|accessTo| ,sesame-repository-uri ,repository-uri)
354
(spocq.a:|quad| ,read-access-node |acl|:|mode| |acl|:|Read| ,repository-uri)
355
(spocq.a:|quad| ,read-access-node |acl|:|agent| |urn:dydra|:|User| ,repository-uri)
356
(spocq.a:|quad| ,read-access-node |acl|:|agent| |foaf|:|Agent| ,repository-uri)
358
,@(loop for collaboration in (mysql-collaboration-records account_cached_slug cached_slug)
359
append (destructuring-bind (&key account repository collaborator read write) collaboration
360
(declare (ignore account repository))
361
(let ((collaborator-user-uri (intern-iri (format nil "http://~a/users/~a" site-name collaborator)))
362
(collaborator-account-uri (compute-account-identifier collaborator))
363
(collaborator-node (cons-global-blank-node :prefix "acl")))
364
`((spocq.a:|quad| ,collaborator-node |acl|:|accessTo| ,repository-uri ,repository-uri)
365
(spocq.a:|quad| ,collaborator-node |acl|:|accessTo| ,graphstore-repository-uri ,repository-uri)
366
(spocq.a:|quad| ,collaborator-node |acl|:|accessTo| ,metadata-repository-uri ,repository-uri)
367
(spocq.a:|quad| ,collaborator-node |acl|:|accessTo| ,sesame-repository-uri ,repository-uri)
368
,@(when (equal read "1")
369
`((spocq.a:|quad| ,collaborator-node |acl|:|mode| |acl|:|Read| ,repository-uri)))
370
,@(when (equal write "1")
371
`((spocq.a:|quad| ,collaborator-node |acl|:|mode| |acl|:|Write| ,repository-uri)))
372
(spocq.a:|quad| ,collaborator-node |acl|:|agent| ,collaborator-account-uri ,repository-uri)
373
(spocq.a:|quad| ,collaborator-node |acl|:|agent| ,collaborator-user-uri ,repository-uri)))))
375
;; repository configuration
376
,@(when default_repository_prefixes
377
(multiple-value-bind (prefixes base)
378
(split-prefixes-setting default_repository_prefixes)
379
(append (when prefixes
380
`((spocq.a:|quad| ,repository-uri |urn:dydra|:|prefixes| ,prefixes ,repository-uri)))
382
`((spocq.a:|quad| ,repository-uri |urn:dydra|:|baseIRI| ,base ,repository-uri))))))
384
;; repository profile
386
`((spocq.a:|quad| ,repository-uri |cc|:|license| ,(intern-iri license_url) ,repository-uri)))
387
,@(when (plusp (length homepage)) ;; leave it as a string
388
`((spocq.a:|quad| ,repository-uri |foaf|:|homepage| ,homepage ,repository-uri)))
389
,@(when (or (plusp (length summary)) (plusp (length description)))
390
`((spocq.a:|quad| ,repository-uri |dc|:|description|
391
,(format nil "~@[~a~]~:[~;~%~%~]~@[~a~]" summary (and summary description) description)
393
,@(apply #'mysql-repository-view-statements account-slug repository-slug args)
396
;;; (pprint-sse (mysql-account-metadata-statements "jhacker"))
397
;;; (pprint-sse (mysql-repository-metadata-statements "jhacker" "tbl-extended"))
398
;;; (pprint-sse (mysql-repository-metadata-statements "nxp" "plm"))
399
;;; (pprint-sse (mysql-repository-metadata-statements "james" "foaf"))
401
(defun mysql-repository-view-statements (account-slug repository-slug &rest args)
402
"Transliterate repository metadata from a mysql table to statements in the system and respective account
403
repositories. The system entries are writte into the default graph in order to be readily accessible.
404
They identify and classify the repository and specify its ownership and constituency.
405
The account entries are written into a repository-specific graph as the repository id is known
406
when they are retrieved.
408
see http://spinrdf.org/sp, which defined the prefix for sp as http://spinrdf.org/sp#
411
(let ((view-records (apply #'mysql-repository-view-records account-slug repository-slug args))
412
(repository-records (make-hash-table :test 'equal))
413
;; retrieve collaboration here for the view - may be a second time
414
(collaboration-records (mysql-collaboration-records account-slug repository-slug)))
415
(loop for view-record in view-records
416
append (destructuring-bind (&key account_cached_slug repository_cached_slug uuid name
417
((:cached_slug view_cached_slug) (error "missing view name"))
419
&allow-other-keys) view-record
420
(declare (ignore uuid )) ;; not consistent with catalog
421
(let ((repository-record (or (gethash (list account_cached_slug repository_cached_slug) repository-records)
422
(setf (gethash (list account_cached_slug repository_cached_slug) repository-records)
423
;; nb - retriev the repository metadata a second time
424
(first (apply #'mysql-repository-metadata-records account_cached_slug repository_cached_slug args)))
425
(error "no repository entry for view: ~s ~s ~s" account_cached_slug repository_cached_slug view_cached_slug))))
426
(destructuring-bind (&key privacy_setting permissible_ip_addresses
427
&allow-other-keys) repository-record
428
(let* ((site-name (site-name))
429
(owner-uri (intern-iri (format nil "http://~a/users/~a" site-name account_cached_slug)))
430
(repository-uri (compute-repository-identifier account_cached_slug repository_cached_slug))
431
(view (make-view :repository-id (make-repository-id :account-name account_cached_slug :repository-name repository_cached_slug)
432
:name view_cached_slug))
433
(view-uri (spocq.i::view-identifier view))
434
(owner-access-node (cons-global-blank-node :prefix "acl"))
435
(access-node (cons-global-blank-node :prefix "acl")))
436
`((spocq.a:|quad| ,view-uri |rdf|:|type| |urn:dydra|:|View| ,repository-uri)
437
(spocq.a:|quad| ,view-uri |foaf|:|name| ,view_cached_slug ,repository-uri)
438
(spocq.a:|quad| ,view-uri |dc|:|title| ,name ,repository-uri)
439
(spocq.a:|quad| ,view-uri |sioc|:|has_owner| ,owner-uri ,repository-uri)
440
,@(when (plusp (length summary))
441
`((spocq.a:|quad| ,view-uri |dc|:|description| ,summary ,repository-uri)))
442
(spocq.a:|quad| ,view-uri <http://spinrdf.org/sp#text> ,query_text ,repository-uri)
443
;; access control for the view, similar as for its repository
444
(spocq.a:|quad| ,owner-access-node |acl|:|accessTo| ,view-uri ,repository-uri)
445
(spocq.a:|quad| ,owner-access-node |acl|:|mode| |acl|:|Read| ,repository-uri)
446
(spocq.a:|quad| ,owner-access-node |acl|:|mode| |acl|:|Write| ,repository-uri)
447
(spocq.a:|quad| ,owner-access-node |acl|:|mode| |acl|:|Execute| ,repository-uri)
448
(spocq.a:|quad| ,owner-access-node |acl|:|agent| ,owner-uri ,repository-uri)
449
,@(cond ((equal privacy_setting "1") ; owner only is in the initial graph above
451
((equal privacy_setting "2") ; ... plus write by ip
452
`((spocq.a:|quad| ,access-node |acl|:|accessTo| ,view-uri ,repository-uri)
453
(spocq.a:|quad| ,access-node |acl|:|mode| |acl|:|Execute| ,repository-uri)
454
(spocq.a:|quad| ,access-node |acl|:|agent| |urn:dydra|:|LocatedAgent| ,repository-uri)
455
,@(when (plusp (length permissible_ip_addresses))
456
(loop for address in (split-string permissible_ip_addresses #(#\,))
457
collect `(spocq.a:|quad| ,access-node |sioc|:|ip_address| ,address ,repository-uri)))))
458
((equal privacy_setting "3") ; ... plus read access for authenticated users
459
`((spocq.a:|quad| ,access-node |acl|:|accessTo| ,view-uri ,repository-uri)
460
(spocq.a:|quad| ,access-node |acl|:|mode| |acl|:|Execute| ,repository-uri)
461
(spocq.a:|quad| ,access-node |acl|:|agent| |urn:dydra|:|User| ,repository-uri)))
462
((equal privacy_setting "4") ; owner plus read by ip or authenticated user
463
`((spocq.a:|quad| ,access-node |acl|:|accessTo| ,view-uri ,repository-uri)
464
(spocq.a:|quad| ,access-node |acl|:|mode| |acl|:|Execute| ,repository-uri)
465
(spocq.a:|quad| ,access-node |acl|:|agent| |urn:dydra|:|User| ,repository-uri)
466
(spocq.a:|quad| ,access-node |acl|:|agent| |urn:dydra|:|LocatedAgent| ,repository-uri)
467
,@(when (plusp (length permissible_ip_addresses))
468
(loop for address in (split-string permissible_ip_addresses #(#\,))
469
collect `(spocq.a:|quad| ,access-node |sioc|:|ip_address| ,address ,repository-uri)))))
470
((equal privacy_setting "5") ; anonymous execute access
471
`((spocq.a:|quad| ,access-node |acl|:|accessTo| ,view-uri ,repository-uri)
472
(spocq.a:|quad| ,access-node |acl|:|mode| |acl|:|Execute| ,repository-uri)
473
(spocq.a:|quad| ,access-node |acl|:|agent| |urn:dydra|:|User| ,repository-uri)
474
(spocq.a:|quad| ,access-node |acl|:|agent| |foaf|:|Agent| ,repository-uri)
477
(warn "no privacy setting for view: ~s ~s ~s" account_cached_slug repository_cached_slug view_cached_slug)
479
,@(loop for collaboration in collaboration-records
480
append (destructuring-bind (&key account repository collaborator read write) collaboration
481
(declare (ignore account repository))
482
(let ((collaborator-user-uri (intern-iri (format nil "http://~a/users/~a" site-name collaborator)))
483
(collaborator-account-uri (compute-account-identifier collaborator))
484
(collaborator-node (cons-global-blank-node :prefix "acl")))
485
`((spocq.a:|quad| ,collaborator-node |acl|:|accessTo| ,view-uri ,repository-uri)
486
,@(when (equal read "1")
487
`((spocq.a:|quad| ,collaborator-node |acl|:|mode| |acl|:|Execute| ,repository-uri)))
488
,@(when (equal write "1")
489
`((spocq.a:|quad| ,collaborator-node |acl|:|mode| |acl|:|Read| ,repository-uri)
490
(spocq.a:|quad| ,collaborator-node |acl|:|mode| |acl|:|Write| ,repository-uri)
491
(spocq.a:|quad| ,collaborator-node |acl|:|mode| |acl|:|Execute| ,repository-uri)))
492
(spocq.a:|quad| ,collaborator-node |acl|:|agent| ,collaborator-account-uri ,repository-uri)
493
(spocq.a:|quad| ,collaborator-node |acl|:|agent| ,collaborator-user-uri ,repository-uri))))))
496
(defun synchronize-repository-view-metadata (account repository)
497
(let ((account-metadata-repository (make-repository-id :account-name account :repository-name "system")))
498
(flet ((filter-field (field)
499
(loop for stmt in field when (stringp (third stmt)) do (error "invalid statement: ~s" stmt))
500
(loop for stmt in field
502
do (warn "incomplete statement: ~s" stmt)
504
(with-open-transaction (account-metadata-repository :normal-disposition :commit :read-only-p nil)
505
(repository-insert-field *transaction* (filter-field (mysql-repository-view-statements account repository)))))))
507
;;; (mysql-repository-view-statements "james" "foaf")
508
;;; (synchronize-repository-view-metadata "james" "foaf")
509
;;; (synchronize-repository-view-metadata "test" "test")
512
(defgeneric account-settings-statements (account)
513
(:method ((account account))
514
(account-settings-statements (account-name account)))
516
(:method ((account-name string))
517
(let* ((account-catalog-pathname (account-catalog-pathname account-name)) ;; the directory
518
(*package* (find-package :spocq.i))
519
(account-uri (compute-account-identifier account-name))
520
(account-metadata-pathname (make-pathname :name "metadata" :type "sxp" :directory (pathname-directory account-catalog-pathname))))
522
(when (probe-file account-metadata-pathname)
523
(with-open-file (stream account-metadata-pathname :direction :input)
524
(loop for setting = (read stream nil nil)
526
for (name value) = setting
527
for property = (find-property-symbol name "urn:dydra")
528
for decoded-value = (when property
529
(handler-case (decode-configuration-parameter value property)
530
(error (c) (log-warn "account-settings-statements: ~s: ~a" property c) nil)))
532
collect `(spocq.a:|quad| ,account-uri ,property ,decoded-value ,account-uri))))
533
(loop for pathname in (directory (make-pathname :name :wild :directory (pathname-directory account-catalog-pathname)))
534
for property = (find-property-symbol (pathname-name pathname) "urn:dydra")
535
for decoded-value = (when property
536
(handler-case (let* ((text (read-file pathname)))
537
(when (plusp (length text)) (decode-configuration-parameter text property)))
538
(error (c) (log-warn "account-settings-statements2: ~s: ~a" pathname c) nil)))
540
collect `(spocq.a:|quad| ,account-uri ,property ,decoded-value ,account-uri))
541
(loop for account-repository-pathname in (directory (merge-pathnames (make-pathname :directory '(:relative "repositories") :name :wild)
542
account-catalog-pathname))
543
for repository-name = (pathname-name account-repository-pathname)
544
for repository-id = (compute-repository-id account-name repository-name)
545
for repository-uri = (compute-repository-identifier account-name repository-name)
546
for repository-catalog-pathname = (repository-catalog-pathname repository-id)
547
for repository-metadata-pathname = (make-pathname :name "metadata" :type "sxp" :directory (pathname-directory repository-catalog-pathname))
548
when (probe-file repository-metadata-pathname)
549
append (with-open-file (stream repository-metadata-pathname :direction :input)
550
(loop for setting = (read stream nil nil)
552
for (name value) = setting
553
for property = (find-property-symbol name "urn:dydra")
554
for decoded-value = (when property
555
(handler-case (decode-configuration-parameter value
557
(error (c) (log-warn "account-settings-statements: ~s: ~a" property c) nil)))
559
collect `(spocq.a:|quad| ,repository-uri ,property, decoded-value ,repository-uri)))
560
append (loop for pathname in (directory (make-pathname :name :wild :defaults repository-catalog-pathname))
561
for property = (find-property-symbol (pathname-name pathname) "urn:dydra")
562
for decoded-value = (when property
563
(handler-case (let* ((text (read-file pathname)))
564
(when (plusp (length text)) (decode-configuration-parameter text property)))
565
(error (c) (log-warn "account-settings-statements: ~s4: ~a" pathname c) nil)))
567
collect `(spocq.a:|quad| ,repository-uri ,property ,decoded-value ,repository-uri)))))))
570
(defun synchronize-from-mysql (mysql-spec &key (account-names (apply #'mysql-account-list mysql-spec)) (verbose nil)
571
(clear-repository '(:account))
573
;; initialize the system repository
574
(unless (repository-exists-p *system-repository-id*)
576
(format *trace-output* "~&--- initializing system"))
577
(create-repository *system-repository-id*)
578
(remf clear-repository :system)
580
;; generate the given acount information
581
(flet ((filter-field (field)
582
(loop for stmt in field when (stringp (third stmt)) do (error "invalid statement: ~s" stmt))
583
(loop for stmt in field
585
do (warn "incomplete statement: ~s" stmt)
587
(let* ((*print-pretty* nil)
589
(loop for account-name in account-names
590
for admin-p = (find account-name admins :test #'string-equal)
591
;; separate the user-editables from the system-controlled metadata
592
;; the system repository holds : the account naming and numbering, owner description and ownership relation
593
append (let ((account-repository-name (format nil "~a/system" account-name))
594
(account-settings (account-settings-statements account-name)))
595
;; extract the account's user-controlled and system-wide metadata
596
(destructuring-bind (&key ((:system account-system-metadata) nil) ((:account account-user-metadata) nil))
597
(apply #'mysql-account-metadata-statements account-name mysql-spec)
598
;; augment those with the analogous data fro each repository
599
(loop for repository-metadata in (apply #'mysql-repository-metadata-statements account-name nil mysql-spec)
600
do (destructuring-bind (&key ((:system repository-system-metadata) nil) ((:account repository-user-metadata) nil))
602
(setf account-user-metadata (append account-user-metadata repository-user-metadata))
603
(setf account-system-metadata (append account-system-metadata repository-system-metadata))))
604
(unless (repository-exists-p account-repository-name)
605
(unless (create-repository account-repository-name)
606
(error "cannot create repository: ~s" account-repository-name)))
608
(format *trace-output* "~&~%--- account repository ~a, ~s statements"
609
account-repository-name (length (append account-user-metadata account-settings)))
610
(map nil #'(lambda (stmt &aux (*print-pretty* nil))
612
(append account-user-metadata account-settings)))
613
;; save the user-controlled data in the account metadata repository
614
(with-open-transaction (account-repository-name :normal-disposition :commit :read-only-p nil)
615
(when (member :account clear-repository) (repository-clear-graph *transaction* :all))
616
(repository-insert-field *transaction* (filter-field (append account-user-metadata account-settings)))
617
(commit-transaction *transaction*))
618
;; collect the system-wide data
620
(let ((owner-uri (intern-iri (format nil "http://dydra.com/users/~a" account-name)))
621
(site-uri (intern-iri "http://dydra.com")))
622
(push `(spocq.a:|quad| ,owner-uri |sioc|:|administrator_of| ,site-uri |urn:dydra|:|users|)
623
account-system-metadata)))
624
account-system-metadata)))))
627
(format *trace-output* "~&~%--- system")
628
(map nil #'(lambda (stmt &aux (*print-pretty* nil))
631
(with-open-transaction (*system-repository-id* :normal-disposition :commit :read-only-p nil)
632
(when (member :system clear-repository)
633
(repository-clear-graph *transaction* :all))
634
(repository-insert-field *transaction*
635
(append (filter-field system-metadata)
636
(system-class-metadata)))
637
(commit-transaction *transaction*))))
640
(defun synchronize-repository-from-mysql (mysql-spec account-name repository-name &key (verbose nil))
641
"synchronize metadata for just one repository"
642
;; generate the given account/repository information
643
(flet ((filter-field (field)
644
(loop for stmt in field when (stringp (third stmt)) do (error "invalid statement: ~s" stmt))
645
(loop for stmt in field
647
do (warn "incomplete statement: ~s" stmt)
649
(let* ((*print-pretty* nil)
650
(account-repository-name (format nil "~a/system" account-name))
651
(repository-uri (compute-repository-identifier account-name repository-name))
652
(metadata-repository-uri (intern-iri (format nil "http://~a/accounts/~a/repositories/~a" (site-name) account-name repository-name)))
653
(repository-metadata (apply #'mysql-repository-metadata-statements account-name repository-name mysql-spec)))
654
(when (rest repository-metadata)
655
(log-warn "synchronize-repository-from-mysql: extra repository metadata ignored: ~a ~a: ~s"
656
account-name repository-name
657
(rest repository-metadata)))
658
(destructuring-bind (&key ((:system repository-system-metadata) nil) ((:account repository-account-metadata) nil))
659
(first repository-metadata)
660
(unless (repository-exists-p account-repository-name)
661
(unless (create-repository account-repository-name)
662
(error "cannot create repository: ~s" account-repository-name)))
664
(format *trace-output* "~&~%--- repository account ~a ~s statements"
665
account-repository-name
666
(length repository-account-metadata))
667
(map nil #'(lambda (stmt &aux (*print-pretty* nil))
669
repository-account-metadata))
670
;; save the user-controlled data in the account metadata repository
671
(with-open-transaction (account-repository-name :normal-disposition :commit :read-only-p nil)
672
(repository-clear-graph *transaction* metadata-repository-uri)
673
(repository-insert-field *transaction* (filter-field repository-account-metadata))
674
(commit-transaction *transaction*))
676
(format *trace-output* "~&~%--- repository system ~s statements"
677
(length repository-system-metadata))
678
(map nil #'(lambda (stmt &aux (*print-pretty* nil))
680
repository-system-metadata))
681
(with-open-transaction (*system-repository-id* :normal-disposition :commit :read-only-p nil)
682
(let ((existing-field (repository-match-field *transaction* <urn:dydra:all> repository-uri '?::p '?::o)))
684
(repository-delete-field *transaction* existing-field)))
685
(repository-insert-field *transaction* (filter-field repository-system-metadata))
686
(commit-transaction *transaction*)))
687
metadata-repository-uri)))
690
(defun system-class-metadata ()
691
(let ((statements '((spocq.a:|triple| |rdfs|:|Class| |rdf|:|type| |rdfs|:|Class|)
692
(spocq.a:|triple| |sioc|:|UserAccount| |rdf|:|type| |rdfs|:|Class|)
693
(spocq.a:|triple| |foaf|:|Person| |rdf|:|type| |rdfs|:|Class|)
694
(spocq.a:|triple| |foaf|:|Agent| |rdf|:|type| |rdfs|:|Class|)
695
(spocq.a:|triple| <http://purl.org/dc/terms/Dataset> |rdf|:|type| |rdfs|:|Class|)
696
(spocq.a:|triple| |urn:dydra|:|Account| |rdf|:|type| |rdfs|:|Class|)
697
(spocq.a:|triple| |urn:dydra|:|Account| |rdfs|:|subClassOf| |sioc|:|UserAccount|)
698
(spocq.a:|triple| |urn:dydra|:|Repository| |rdf|:|type| |rdfs|:|Class|)
699
(spocq.a:|triple| |urn:dydra|:|Repository| |rdfs|:|subClassOf| <http://purl.org/dc/terms/Dataset>)
700
(spocq.a:|triple| |urn:dydra|:|Group| |rdfs|:|subClassOf| <http://purl.org/dc/terms/Dataset>)
701
;; w3c acl does not describe the authenticated agent as a subclass of agent
702
(spocq.a:|triple| |acl|:|AuthenticatedAgent| |rdf|:|type| |rdfs|:|Class|)
703
(spocq.a:|triple| |acl|:|AuthenticatedAgent| |rdfs|:|subClassOf| |foaf|:|Agent|)
704
(spocq.a:|triple| |urn:dydra|:|User| |rdf|:|type| |rdfs|:|Class|)
705
(spocq.a:|triple| |urn:dydra|:|User| |rdfs|:|subClassOf| |foaf|:|Person|)
706
;; materialize the subclass relation
707
(spocq.a:|triple| |urn:dydra|:|User| |rdfs|:|subClassOf| |foaf|:|Agent|)
708
(spocq.a:|triple| |urn:dydra|:|User| |rdfs|:|subClassOf| |acl|:|AuthenticatedAgent|)
709
(spocq.a:|triple| |urn:dydra|:|LocatedAgent| |rdf|:|type| |rdfs|:|Class|)
710
(spocq.a:|triple| |urn:dydra|:|LocatedAgent| |rdfs|:|subClassOf| |foaf|:|Agent|)
711
(spocq.a:|triple| |urn:dydra|:|View| |rdf|:|type| |rdfs|:|Class|)
712
(spocq.a:|triple| |urn:dydra|:|Manager| |rdf|:|type| |rdfs|:|Class|)
713
(spocq.a:|triple| |urn:dydra|:|Manager| |rdfs|:|subClassOf| |urn:dydra|:|User|)
714
(spocq.a:|triple| |urn:dydra|:|Administrator| |rdf|:|type| |rdfs|:|Class|)
715
(spocq.a:|triple| |urn:dydra|:|Administrator| |rdfs|:|subClassOf| |urn:dydra|:|Manager|))))
716
;;(map nil #'print statements)
719
(defun initialize-system-class-metadata ()
720
(with-open-transaction (*system-repository-id* :normal-disposition :commit :read-only-p nil)
721
(repository-insert-field *transaction* (system-class-metadata))))
723
(defun synchronize-views-from-mysql (mysql-spec account-name &key (repositories (account-repositories account-name))
724
(repository-ids (mapcar #'repository-id repositories))
725
(account-repository-name (make-repository-id :repository-name "system" :account-name account-name)))
727
(flet ((filter-field (field)
728
(loop for stmt in field
730
do (warn "incomplete statement: ~s" stmt)
732
(let* ((*print-pretty* nil)
734
(loop for repository-id in repository-ids
735
for repository-name = (nth-value 1 (parse-repository-id repository-id))
736
append (apply #'mysql-repository-view-statements account-name repository-name mysql-spec))))
737
(when account-repository-name
738
(with-open-transaction (account-repository-name :normal-disposition :commit :read-only-p nil)
739
(repository-insert-field *transaction* (filter-field view-metadata))
740
(commit-transaction *transaction*)))
741
(values view-metadata
743
;;; (mysql-repository-view-statements "nxp" "plm")
744
;;; (mapcar #'length (multiple-value-list (synchronize-views-from-mysql nil "nxp"))) ; :account-repository-name nil)
746
(defun update-uuids ()
747
(let* ((accounts-repositories (account-and-repository-names))
748
(uuid-statements (loop for (account-name . repository-names) in accounts-repositories
749
append (when (account-exists-p account-name)
750
(let ((account-uri (compute-account-identifier account-name))
751
(account-uuid (intern-uuid (account-uuid account-name))))
752
(cons `(spocq.a:|quad| ,account-uri <http://dydra.com/operations#uuid> ,account-uuid ,account-uri)
753
(loop for repository-name in repository-names
754
for repository-id = (make-repository-id :account-name account-name :repository-name repository-name)
755
for repository-uri = (compute-repository-identifier account-name repository-name)
756
for repository-uuid = (when (repository-exists-p repository-id)
757
(intern-uuid (repository-uuid repository-id)))
759
collect `(spocq.a:|quad| ,repository-uri <http://dydra.com/operations#uuid> ,repository-uuid ,account-uri))))))))
760
(flet ((remove-uuids ()
761
(run-sparql-internal "delete {graph ?g { ?s <http://dydra.com/operations#uuid> ?o} }
762
where {graph ?g { ?s <urn:dydra:prefixes> ?o} }"
763
:repository-id *system-repository-id*
764
:agent (system-agent)))
766
(with-open-transaction (*system-repository-id* :normal-disposition :commit :read-only-p nil)
767
(repository-insert-field *transaction* uuid-statements))))
773
(defun print-account-metadata (accounts)
774
(loop for account in accounts
775
with *print-pretty* = nil
776
with *package* = (find-package :spocq.a)
777
do (progn (print account)
778
(format t "~&~{~s~%~}~%" (second (mysql-account-metadata-statements account))))))
781
(defun split-prefixes-setting (string)
782
(if (plusp (length string))
783
(if (search "base" string :test #'char-equal)
784
(multiple-value-bind (prefixes base) (parse-prefix-bindings string)
785
(values (with-output-to-string (stream)
786
(loop for (prefix . namespace) in prefixes
787
do (format stream "PREFIX ~a: ~a~%" prefix namespace)))
790
;; always parse and reformat
791
(defun split-prefixes-setting (string)
792
(if (plusp (length string))
793
(multiple-value-bind (prefixes base) (parse-prefix-bindings string)
794
(values (with-output-to-string (stream)
795
(loop for (prefix . namespace) in prefixes
796
do (format stream "PREFIX ~a: ~a~%" prefix namespace)))
799
(defun replace-agent-class (repository-id)
800
"replace all uses of agent with agent class.
801
reduce error in queries."
802
(run-sparql-internal "
803
insert {graph ?g { ?s <http://www.w3.org/ns/auth/acl#agent> ?o} }
804
where {graph ?g { ?s <http://www.w3.org/ns/auth/acl#agentClass> ?o} }
806
:repository-id repository-id
807
:agent (system-agent)))
808
;; (replace-agent-class "james/system")
809
;; (loop for repo in (list-all-repositories) when (search "/system" repo) do (replace-agent-class repo))
811
(defun remove-empty-prefixes (repository-id)
812
(run-sparql-internal "
813
delete {graph ?g { ?s <urn:dydra:prefixes> ''} }
814
where {graph ?g { ?s <urn:dydra:prefixes> ''} }
816
:repository-id repository-id
817
:agent (system-agent)))
818
;;; (remove-empty-prefixes "james/system")
819
(defun remove-prefix-metadata (repository-id)
820
(run-sparql-internal "
821
delete {graph ?g { ?s <urn:dydra:prefixes> ?o} }
822
where {graph ?g { ?s <urn:dydra:prefixes> ?o} }
824
:repository-id repository-id
825
:agent (system-agent)))
826
;;; (remove-prefix-metadata "james/system")
829
(defun update-system-metadata (&key (verbose nil))
830
(flet ((filter-field (field)
831
(loop for stmt in field
833
do (warn "incomplete statement: ~s" stmt)
835
(let ((system-metadata (compute-initial-repository-authorization-graph "system" "system")))
837
(map nil 'print system-metadata))
838
(with-open-transaction (*system-repository-id* :normal-disposition :commit :read-only-p nil)
839
(repository-insert-field *transaction* (filter-field system-metadata))
840
(commit-transaction *transaction*)))))
842
;;; (update-system-metadata :verbose t)
844
(with-open-repository ("james/system" :normal-disposition :commit :read-only-p nil)
845
(spocq.e:delete-data #p"/srv/dydra/catalog/repositories/677da748-0a62-40d9-9f79-bd93fd7d2273/metadata/account.bak"))
850
(in-package :spocq.i)
853
(initialize-system-class-metadata)
854
(update-system-metadata)
856
;; 2015-08-15, 2015-10-23
858
(setq *mysql-database* "stage")
859
(setq *mysql-host* "localhost")
861
;; small examinations
862
(defun print-statement (stmt &aux (*print-pretty* nil)) (print stmt))
863
(mysql-account-metadata-records "openrdf-sesame")
864
(mysql-account-metadata-statements "james")
865
(mysql-repository-metadata-records "openrdf-sesame" "mem-rdf")
866
(mysql-repository-metadata-statements "eknutov" "nxp-erp")
867
(account-settings-statements "james" :admin-p t)
868
(print-account-metadata '("openrdf-sesame" "james" "jhacker"))
869
(synchronize-from-mysql nil :account-names '("openrdf-sesame" "james" "jhacker") :clear-repository () :admins '("james"))
871
(synchronize-from-mysql nil :account-names '("james" "operations" "jhacker") :clear-repository () :admins '("james"))
872
(synchronize-from-mysql nil :account-names '("james" ) :clear-repository '(:account) :admins '("james"))
874
(pprint-sse (mysql-account-metadata-statements "openrdf-sesame"))
875
(pprint-sse (first (mysql-repository-metadata-statements "openrdf-sesame" nil)))
876
(pprint-sse (account-settings-statements "jhacker"))
878
(pprint-sse (mysql-account-metadata-statements "stw"))
879
(synchronize-from-mysql nil :account-names '("stw") :clear-repository ())
880
(synchronize-from-mysql nil :account-names '("schema") :clear-repository ())
881
(synchronize-from-mysql nil :account-names '("schema-org-test") :clear-repository ())
883
(synchronize-from-mysql nil :account-names '("json-ld") :clear-repository ())
885
(synchronize-from-mysql nil :account-names '("eknutov") :clear-repository ())
887
(synchronize-from-mysql nil :account-names '("sba") :clear-repository ())
889
(synchronize-from-mysql nil :account-names '("test") :clear-repository '(:account))
890
;; 20201211@nl4 : the repository evolved from older systems
891
(run-sparql-internal "
892
drop graph <http://dydra.com/accounts/hemeda2>;
893
drop graph <http://dydra.com/accounts/sonicliving>;
895
:repository-id "system/system" :agent (system-agent))
900
(mysql-account-metadata-statements "greentara")
901
(mysql-repository-metadata-statements "greentara" nil)
902
(synchronize-from-mysql nil :account-names '("greentara") :clear-repository ())
904
;; transport the content
906
(let* ((process (sb-ext:run-program "/opt/dydra/bin/dydra-admin" '("list-accounts") :input nil :output :stream :wait nil))
907
(stream (sb-ext:process-output process))
908
(account-names (loop for name = (read-line stream nil nil) until (null name) collect name)))
909
(sb-ext:process-close process)
911
(synchronize-from-mysql nil :account-names account-names ; :clear-repository ()
912
:admins '("james" "bendiken" "system")))
914
;; transport a single account
915
(synchronize-from-mysql nil :account-names '("bendiken") :clear-repository ()
916
:admins '("james" "bendiken" "system"))
918
(synchronize-from-mysql nil :account-names '("james") :clear-repository ()
920
(run-sparql-internal "select ?g ?s ?o where { {graph ?g { ?s <http://rdfs.org/sioc/ns#administrator_of> ?o } }
922
{ ?s <http://rdfs.org/sioc/ns#administrator_of> ?o } }"
923
:repository-id "system/system" :agent (system-agent))
927
(pprint-sse (read-instance-metadata-statements (account "james")))
928
(pprint-sse (read-instance-metadata-statements (repository "james/test" :account (account "james"))))
929
(let ((a (account "james"))) (time (dotimes (x 10) (read-instance-metadata a))))
930
(pprint-sse (read-instance-metadata (repository "jhacker/726-base" :account (account "jhacker"))))
931
(instance-metadata (repository "jhacker/726-base" :account (account "jhacker")))
933
(run-sparql-internal "select * where { {graph ?g {?s ?p ?o}} union {?s ?p ?o}}" :repository-id *system-repository-id*)
934
(run-sparql-internal "select (count (*) as ?count) where { {graph ?g {?s ?p ?o}} union {?s ?p ?o}}" :repository-id "james/system")
935
(run-sparql-internal "select * where { {graph ?g {?s ?p ?o}} union {?s ?p ?o}}" :repository-id "system/system")
936
(run-sparql-internal "select * where { {graph ?g {?s ?p ?o}} union {?s ?p ?o}}" :repository-id "258/1661")
938
(time (dotimes (x 10)
939
(flet ((match-field (context subject predicate object)
940
(let ((field (repository-matrix-field *transaction* context subject predicate object)))
941
(prog1 (term-value-field field)
942
(release-field-data field)))))
943
(with-open-transaction ("system/system") (match-field |urn:dydra|:|all| '?::s '?::p '?::o)))))
946
(defun repository-field-list (repository-id)
947
(flet ((match-field (context subject predicate object)
948
(let ((field (repository-matrix-field *transaction* context subject predicate object)))
949
(prog1 (term-value-field field)
950
(release-field-data field)))))
951
(with-open-transaction (repository-id) (match-field |urn:dydra|:|all| '?::s '?::p '?::o))))
954
(time (dotimes (x 10) (repository-field-list "258/1661")))
955
(map nil #'print-statement (repository-field-list "system/system"))
956
(map nil #'print-statement (repository-field-list "jhacker/system"))
957
(run-sparql-internal "select * where { {graph ?g { ?s ?p ?o } } union { ?s ?p ?o } }" :repository-id "jhacker/system")
959
;; 0.013s = a 10x factor for not needing to translate external to internal
961
(split-prefixes-setting "base <http://test>
962
@prefix : <http://test2>")
963
(split-prefixes-setting "base <http://test>
964
prefix x: <http://test3>
965
PREFIX y: <http://test4>
966
prefix : <http://test2>")
968
(parse-prefix-bindings "base <http://test>
969
prefix : <http://test2>
970
PREFIX x: <http://test3>")
971
(parse-prefix-bindings "prefix : <http://test2>
972
PREFIX x: <http://test3>")
974
(setq *namespace-bindings*
976
'(("plm" . <http://data.nxp.com/def/plm/>)
977
("nxp" . <http://purl.org/nxp/schema/v1/>)
978
("plib" . <http://purl.org/plib/dictionary.owl#>)
979
("spc" . <http://qa.data.nxp.com/def/spc/>))
980
*namespace-bindings*))
982
;;; move from agent class to agent
984
(run-sparql-internal "
986
where {graph ?g { ?s <http://www.w3.org/ns/auth/acl#agent> ?o . ?s <http://www.w3.org/ns/auth/acl#agentClass> ?o} }
988
:repository-id "openrdf-sesame/system"
989
:agent (system-agent))
991
(run-sparql-internal "
993
where {graph ?g { ?s <http://www.w3.org/ns/auth/acl#agent> ?o} }
995
:repository-id "openrdf-sesame/system"
996
:agent (system-agent))
999
(run-sparql-internal "
1000
insert {graph ?g { ?s <http://www.w3.org/ns/auth/acl#agent> ?o} }
1001
where {graph ?g { ?s <http://www.w3.org/ns/auth/acl#agentClass> ?o} }
1003
:repository-id "openrdf-sesame/system"
1004
:agent (system-agent))
1007
;;; on nexperia-dev, nxp-dev-new
1008
;;; 20200802 : de15a
1009
;;; 20210214 new general values
1010
(run-sparql-internal "
1012
graph <urn:dydra:users> {
1013
<http://dydra.com/users/james> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1014
<http://dydra.com/users/system> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1015
<http://dydra.com/users/frank> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1016
<http://dydra.com/users/mgr> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1017
<http://dydra.com/users/ilabra> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1020
:repository-id "system/system"
1021
:agent (system-agent))
1024
(run-sparql-internal "
1026
graph <urn:dydra:users> {
1027
<http://dydra.com/users/james> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1028
<http://dydra.com/users/system> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1029
<http://dydra.com/users/frank> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1030
<http://dydra.com/users/max> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1031
;; metadata was not propagated
1032
<http://dydra.com/users/openrdf-sesame> <http://purl.org/dc/elements/1.1/title> \"openrdf-sesame\"^^<http://www.w3.org/2001/XMLSchema#string> .
1033
<http://dydra.com/users/openrdf-sesame> <urn:dydra:accessToken> \"81f1d23e41d862d990d067026b5a8295f3b12ad2\"^^<http://www.w3.org/2001/XMLSchema#string>.
1034
<http://dydra.com/users/skorkmaz> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1037
:repository-id "system/system"
1038
:agent (system-agent))
1042
(read-file "/srv/dydra/config/admins.txt")
1043
(run-sparql-internal "
1045
graph <urn:dydra:users> {
1046
<http://dydra.com/users/james> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1047
<http://dydra.com/users/operations> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1048
<http://dydra.com/users/system> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1049
<http://dydra.com/users/support> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1052
:repository-id "system/system"
1053
:agent (system-agent))
1056
(read-file "/srv/dydra/config/admins.txt")
1057
(run-sparql-internal "
1059
graph <urn:dydra:users> {
1060
<http://dydra.com/users/james> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1061
<http://dydra.com/users/operations> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1062
<http://dydra.com/users/system> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1063
<http://dydra.com/users/mgr> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1066
:repository-id "system/system"
1067
:agent (system-agent))
1070
(spocq.i::run-sparql-internal "
1072
graph <urn:dydra:users> {
1073
<http://dydra.com/users/mgr> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> .
1076
:repository-id "system/system"
1077
:agent (spocq.i::system-agent))
1080
(let ((repository-uri (compute-repository-identifier "system" "null"))
1081
(graphstore-repository-uri (intern-iri (format nil "http://~a/~a/~a" (site-name) "system" "null")))
1082
(metadata-repository-uri (intern-iri (format nil "http://~a/accounts/~a/repositories/~a" (site-name) "system" "null")))
1083
(sesame-repository-uri (intern-iri (format nil "http://~a/~a/repositories/~a" (site-name) "system" "null")))
1084
(read-access-node (spocq:blank-node-label (cons-global-blank-node :prefix "acl"))))
1085
(print (list repository-uri graphstore-repository-uri metadata-repository-uri sesame-repository-uri))
1086
(run-sparql-internal (format nil "
1087
prefix foaf: <http://xmlns.com/foaf/0.1/>
1088
prefix acl: <http://www.w3.org/ns/auth/acl#>
1090
graph <http://dydra.com/accounts/system/repositories/null> {
1091
_:acl_system_null <http://www.w3.org/ns/auth/acl#accessTo> <http://dydra.com/accounts/system/repositories/null>;
1092
<http://www.w3.org/ns/auth/acl#accessTo> <http://dydra.com/system/null>;
1093
<http://www.w3.org/ns/auth/acl#mode> <http://www.w3.org/ns/auth/acl#Read> ;
1094
<http://www.w3.org/ns/auth/acl#agent> <urn:dydra:User>;
1095
<http://www.w3.org/ns/auth/acl#agent> <http://xmlns.com/foaf/0.1/Agent> .
1098
:repository-id "system/system"
1099
:agent (system-agent)))
1102
;; 20200429 correct mismatch password
1103
(run-sparql-internal "
1104
delete data {graph <urn:dydra:users> {
1105
<http://dydra.com/users/tibco> <urn:dydra:encryptedPassword> '$2a$10$ZHvQIdTZrLE4c0.MuNgFqekqn63V38U/wsSGDcctF8/gbaMccNX4S'^^<http://www.w3.org/2001/XMLSchema#string>} };
1107
insert data {graph <urn:dydra:users> {
1108
<http://dydra.com/users/tibco> <urn:dydra:encryptedPassword> '$2a$10$HB.HZVDnxTHS7.VN/PF0TeuxEx4.hvst3uLPARHHAvST.lVIeGe8S'^^<http://www.w3.org/2001/XMLSchema#string>} }
1110
:repository-id "system/system"
1111
:agent (system-agent))
1113
;;; 20210203 @nl4 clean up system data
1115
(run-sparql-internal "
1116
delete data {graph <http://dydra.com/accounts/christophe-dupriez> {
1117
<http://dydra.com/accounts/christophe-dupriez> <http://purl.org/dc/elements/1.1/title> 'Christophe Dupriez' .
1118
<http://dydra.com/accounts/christophe-dupriez> <http://xmlns.com/foaf/0.1/accountName> 'christophe-dupriez'^^<http://www.w3.org/2001/XMLSchema#string> .
1119
<http://dydra.com/accounts/christophe-dupriez> <http://rdfs.org/sioc/ns#id> <http://dydra.com/accounts/christophe-dupriez> .
1120
<http://dydra.com/accounts/christophe-dupriez> <http://rdfs.org/sioc/ns#id> '485' .
1121
<http://dydra.com/accounts/christophe-dupriez> <http://rdfs.org/sioc/ns#account_of> <http://dydra.com/users/christophe-dupriez> .
1122
<http://dydra.com/accounts/christophe-dupriez> <http://rdfs.org/sioc/ns#has_owner> <http://dydra.com/users/christophe-dupriez> . } }"
1123
:repository-id "system/system"
1124
:agent (system-agent))
1127
(run-sparql-internal "
1128
delete data { graph <urn:dydra:accounts> {
1129
<http://dydra.com/accounts/asiches> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:dydra:Account> .
1130
<http://dydra.com/accounts/asiches> <http://www.w3.org/ns/auth/acl#owner> <http://dydra.com/users/asiches> . } } ;
1131
delete data { graph <urn:dydra:users> {
1132
<http://dydra.com/users/asiches> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:dydra:User> .
1133
<http://dydra.com/users/asiches> <http://purl.org/dc/elements/1.1/title> 'asiches'^^<http://www.w3.org/2001/XMLSchema#string> .
1134
<http://dydra.com/users/asiches> <http://rdfs.org/sioc/ns#id> <http://dydra.com/users/asiches> .
1135
<http://dydra.com/users/asiches> <urn:dydra:encryptedPassword> '$2a$10$Je5WRH1IQ7wkUn9PsnD9ju9jU1esRG2vv8o4VhmTd9hLdkiL.4TUi'^^<http://www.w3.org/2001/XMLSchema#string> .
1136
<http://dydra.com/users/asiches> <urn:dydra:accessToken> 'GSc6ty9aabdNoU8sxZ5a'^^<http://www.w3.org/2001/XMLSchema#string> . } } ;
1137
delete data { graph <http://dydra.com/accounts/asiches> {
1138
<http://dydra.com/accounts/asiches> <http://purl.org/dc/elements/1.1/title> 'asiches'^^<http://www.w3.org/2001/XMLSchema#string> .
1139
<http://dydra.com/accounts/asiches> <http://xmlns.com/foaf/0.1/accountName> 'asiches'^^<http://www.w3.org/2001/XMLSchema#string> .
1140
<http://dydra.com/accounts/asiches> <http://rdfs.org/sioc/ns#id> <http://dydra.com/accounts/asiches> .
1141
<http://dydra.com/accounts/asiches> <http://rdfs.org/sioc/ns#id> '483' .
1142
<http://dydra.com/accounts/asiches> <http://rdfs.org/sioc/ns#account_of> <http://dydra.com/users/asiches> .
1143
<http://dydra.com/accounts/asiches> <http://rdfs.org/sioc/ns#has_owner> <http://dydra.com/users/asiches> . } } ;
1144
delete data { graph <http://dydra.com/accounts/asiches> {
1145
<http://dydra.com/users/asiches> <http://xmlns.com/foaf/0.1/mbox> 'asiches@gmail.com'^^<http://www.w3.org/2001/XMLSchema#string> .
1146
<http://dydra.com/asiches/bookmarks> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://rdfs.org/ns/void#Dataset> .
1147
<http://dydra.com/asiches/bookmarks> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:dydra:Repository> .
1148
<http://dydra.com/asiches/bookmarks> <http://purl.org/dc/elements/1.1/title> 'bookmarks' .
1149
<http://dydra.com/asiches/bookmarks> <http://www.w3.org/ns/auth/acl#owner> <http://dydra.com/users/asiches> .
1150
<http://dydra.com/asiches/bookmarks> <http://xmlns.com/foaf/0.1/name> 'bookmarks' .
1151
<http://dydra.com/asiches/bookmarks> <http://rdfs.org/sioc/ns#has_parent> <http://dydra.com/accounts/asiches> .
1152
<http://dydra.com/asiches/bookmarks> <http://rdfs.org/sioc/ns#id> <http://dydra.com/asiches/bookmarks> .
1153
<http://dydra.com/asiches/bookmarks> <http://rdfs.org/sioc/ns#id> '1747' .
1154
<http://dydra.com/asiches/bookmarks> <http://rdfs.org/sioc/ns#has_owner> <http://dydra.com/users/asiches> . } }"
1155
:repository-id "system/system"
1156
:agent (system-agent))
1163
(run-sparql-internal "
1165
where {graph ?g { ?s <http://www.w3.org/ns/auth/acl#agentClass> ?o} }
1167
:repository-id "nxp/system"
1168
:agent (system-agent))
1170
(run-sparql-internal "
1172
where {graph ?g { ?s <http://www.w3.org/ns/auth/acl#agent> ?o} }
1174
:repository-id "nxp/system"
1175
:agent (system-agent))
1177
(run-sparql-internal "
1178
insert {graph ?g { ?s <http://www.w3.org/ns/auth/acl#agent> ?o} }
1179
where {graph ?g { ?s <http://www.w3.org/ns/auth/acl#agentClass> ?o} }
1181
:repository-id "nxp/system"
1182
:agent (system-agent))
1184
AUTH_TOKEN=`cat ~/.dydra/dev.nxp.dydra.com.token`
1185
curl http://dev.nxp.dydra.com/nxp/system.dot --user="${AUTH_TOKEN}:"
1187
(run-sparql-internal "
1189
where {graph ?g { ?s <urn:dydra:prefixes> ?o} }
1191
:repository-id "nxp/system"
1192
:agent (system-agent))
1194
(mysql-repository-metadata-records "nxp" "thirdparty-account")
1195
(mysql-repository-metadata-statements "nxp" "thirdparty-account")
1197
(instance-metadata (repository "nxp/thirdparty-account" :account (account "nxp")))
1201
(run-sparql-internal "
1202
insert data {graph <urn:dydra:users> { <http://dydra.com/users/neuber> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com>} }
1204
:repository-id "system/system"
1205
:agent (system-agent))
1207
dydra-import -i application/n-quads system/system /dev/stdin <<EOF
1208
<http://dydra.com/users/jose> <http://rdfs.org/sioc/ns#administrator_of> <http://dydra.com> <urn:dydra:users> .
1213
delete data { graph <http://dydra.com/accounts/nexperia> {
1214
<http://dydra.com/nexperia/tmp1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://rdfs.org/ns/void#Dataset> .
1215
<http://dydra.com/nexperia/tmp1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <urn:dydra:Repository> .
1216
<http://dydra.com/nexperia/tmp1> <http://xmlns.com/foaf/0.1/name> 'tmp1'^^<http://www.w3.org/2001/XMLSchema#string> .
1217
<http://dydra.com/nexperia/tmp1> <http://purl.org/dc/elements/1.1/title> 'tmp1'^^<http://www.w3.org/2001/XMLSchema#string> .
1218
<http://dydra.com/nexperia/tmp1> <http://www.w3.org/ns/auth/acl#owner> <http://dydra.com/users/nexperia> .
1219
<http://dydra.com/nexperia/tmp1> <http://rdfs.org/sioc/ns#has_parent> <http://dydra.com/accounts/nexperia> .
1220
<http://dydra.com/nexperia/tmp1> <http://rdfs.org/sioc/ns#id> '1524' .
1221
<http://dydra.com/nexperia/tmp1> <http://rdfs.org/sioc/ns#id> <http://dydra.com/nexperia/tmp1> .
1222
<http://dydra.com/nexperia/tmp1> <http://rdfs.org/sioc/ns#has_owner> <http://dydra.com/users/nexperia> .
1223
<http://dydra.com/nexperia/tmp1> <http://dydra.com/operations#uuid> <urn:uuid:bdaf211e-edb1-204b-b3a3-605ff04efeae> .
1225
:repository-id "system/system"
1226
:agent (system-agent))
1229
drop graph <http://dydra.com/nexperia/tmp1> "
1230
:repository-id "nexperia/system"
1231
:agent (system-agent))