]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.db/scl/Simantics/DB.scl
New type class MonadE and corresponding monad syntax with edo keyword
[simantics/platform.git] / bundles / org.simantics.scl.db / scl / Simantics / DB.scl
1 import "JavaBuiltin" as Java
2 include "http://www.simantics.org/Layer0-1.1" as L0
3 import "Map" as Map
4
5 infixl 5 (#)
6  
7 effect ReadGraph
8     "graph"
9     "org.simantics.db.ReadGraph"
10
11 effect WriteGraph
12     "graph"
13     "org.simantics.db.WriteGraph"
14     
15 importJava "org.simantics.db.Resource" where
16     "A resource is a node in a semantic graph."
17     data Resource
18     
19     "Returns the 64-bit unique identifier of the resource."
20     @JavaName getResourceId
21     resourceId :: Resource -> Long
22     
23 importJava "org.simantics.db.ReadGraph" where
24     data ReadGraphX
25     
26 instance Ord Resource where
27     compare a b = compare (resourceId a) (resourceId b)
28   
29 instance Show Resource where
30     show r = "#" + show (resourceId r)
31
32 instance Show Statement where
33     show s = "#" + show (resourceId ( subjectOf s)) + "#" + show (resourceId ( predicateOf s)) + "#" + show (resourceId ( objectOf s))
34
35 importJava "org.simantics.db.Statement" where
36     "A statement is an edge in a semantic graph."
37     data Statement
38     
39     @JavaName getSubject
40     subjectOf :: Statement -> Resource
41     @JavaName getPredicate
42     predicateOf :: Statement -> Resource
43     @JavaName getObject
44     objectOf :: Statement -> Resource
45     
46     isAsserted :: Statement -> Resource -> <ReadGraph> Boolean
47     
48 importJava "org.simantics.db.ReadGraph" where
49     "Converts an absolute URI to a resource or returns `Nothing` if there is no such resource."
50     @JavaName getPossibleResource
51     possibleResource :: String -> <ReadGraph> (Maybe Resource)
52     
53     getDataType :: Resource -> <ReadGraph> Datatype
54
55     @JavaName getSupertypes
56     superTypesOf :: Resource -> <ReadGraph> Set.T Resource
57     
58     @private
59     @JavaName getURI
60     uriOfResource :: Resource -> <ReadGraph> String
61     
62     @JavaName getObjects
63     objects_ :: Resource -> Resource -> <ReadGraph> Collection Resource
64     
65     @JavaName getStatements
66     statements_ :: Resource -> Resource -> <ReadGraph> Collection Statement
67     
68     @JavaName hasStatement
69     existsStatement :: Resource -> Resource -> <ReadGraph> Boolean
70     
71     @JavaName hasStatement
72     existsStatement3 :: Resource -> Resource -> Resource -> <ReadGraph> Boolean
73
74     "Assumes that there is exactly one object with the given subject and predicate and returns it."
75     @JavaName getSingleObject
76     singleObject :: Resource -> Resource -> <ReadGraph> Resource
77
78     """
79     If there is exactly one object with the given `subject` and `predicate`,
80     `possibleObject subject predicate` returns it. Otherwise, it returns
81     `Nothing`.
82     """
83     @JavaName getPossibleObject
84     possibleObject :: Resource -> Resource -> <ReadGraph> Maybe Resource
85
86     "Assumes that there is exactly one statement with the given subject and predicate and returns it."
87     @JavaName getSingleStatement
88     singleStatement :: Resource -> Resource -> <ReadGraph> Statement
89
90     @JavaName getPossibleStatement
91     possibleStatement :: Resource -> Resource -> <ReadGraph> Maybe Statement
92
93     @JavaName getRelatedVariantValue
94     relatedVariantValue :: Resource -> Resource -> <ReadGraph> Variant
95
96     @JavaName getRelatedValue
97     relatedValue_ :: Resource -> Resource -> Binding a -> <ReadGraph> a
98     
99     @JavaName getRelatedValue
100     untypedRelatedValue :: Resource -> Resource -> <ReadGraph> a
101
102     @JavaName getRelatedValue2
103     relatedValue2 :: Resource -> Resource -> <ReadGraph> a
104
105     @JavaName getRelatedVariantValue2
106     relatedVariantValue2 :: Resource -> Resource -> <ReadGraph> Variant
107     
108     @JavaName getPossibleRelatedValue
109     possibleRelatedValue_ :: Resource -> Resource -> Binding a -> <ReadGraph> Maybe a
110     
111     @JavaName getPossibleRelatedValue
112     untypedPossibleRelatedValue :: Resource -> Resource -> <ReadGraph> Maybe a
113     
114     @private
115     @JavaName getValue
116     valueOf_ :: Resource -> Binding a -> <ReadGraph> a
117     
118     @private
119     @JavaName getVariantValue
120     variantValueOf_ :: Resource -> <ReadGraph> Variant
121     
122     @JavaName getValue
123     untypedValueOf :: Resource -> <ReadGraph> Dynamic
124     
125     @JavaName getPossibleValue
126     untypedPossibleValueOf :: Resource -> <ReadGraph> Maybe Dynamic
127     
128     @JavaName getInverse
129     inverseOf :: Resource -> <ReadGraph> Resource
130     
131     @JavaName getSingleType
132     singleTypeOf :: Resource -> Resource -> <ReadGraph> Resource
133     
134     @JavaName getPossibleType
135     possibleTypeOf :: Resource -> Resource -> <ReadGraph> Maybe Resource
136     
137     "`isInstanceOf r t` returns true, if `r` is an instance of `t`"
138     isInstanceOf :: Resource -> Resource -> <ReadGraph> Boolean
139     isSubrelationOf :: Resource -> Resource -> <ReadGraph> Boolean
140     isInheritedFrom :: Resource -> Resource -> <ReadGraph> Boolean
141     
142     getRootLibrary :: () -> <ReadGraph> Resource
143     
144     @JavaName getPredicates
145     predicatesOf :: Resource -> <ReadGraph> [Resource]
146
147 importJava "org.simantics.db.layer0.util.ExtendedUris" where
148     "Converts an absolute URI to a resource"
149     @JavaName resolveAbsoluteUri    
150     resource :: String -> <ReadGraph> Resource
151     
152     "Converts a relative URI to a resource starting from the given resource"
153     @JavaName resolveRelativeUri
154     relativeResource :: Resource -> String -> <ReadGraph> Resource
155
156 "Reads the value of a literal that is an object with the given subject and predicate"
157 @inline
158 relatedValue :: Serializable a => Resource -> Resource -> <ReadGraph> a
159 relatedValue s p = relatedValue_ s p binding
160
161 @inline
162 possibleRelatedValue :: Serializable a => Resource -> Resource -> <ReadGraph> Maybe a
163 possibleRelatedValue s p = possibleRelatedValue_ s p binding
164
165 class Browsable a where
166     fromUri :: String -> <ReadGraph> a
167
168     "Returns the URI of the given value."
169     uriOf :: a -> <ReadGraph> String
170   
171     "Reads the name of the value."
172     nameOf :: a -> <ReadGraph> String
173     possibleNameOf :: a -> <ReadGraph> Maybe String
174     
175     valueOf :: Serializable v => a -> <ReadGraph> v
176     
177     variantValueOf :: a -> <ReadGraph> Variant 
178     
179     children :: a -> <ReadGraph> [a]
180     parent :: a -> <ReadGraph> a
181     possibleParent :: a -> <ReadGraph> Maybe a
182     
183     child :: a -> String -> <ReadGraph> a
184     possibleChild :: a -> String -> <ReadGraph> Maybe a
185     
186 instance Browsable Resource where
187     fromUri = resource
188     uriOf = uriOfResource
189     nameOf r = relatedValue r L0.HasName
190     possibleNameOf r = possibleRelatedValue r L0.HasName
191     @inline
192     valueOf r = valueOf_ r binding
193     variantValueOf = variantValueOf_
194     
195     children r = r # L0.ConsistsOf
196     parent r = singleObject r L0.PartOf
197     possibleParent r = possibleObject r L0.PartOf
198     
199     possibleChild = possibleResourceChild
200     child r n = fromJust (possibleResourceChild r n)
201
202 importJava "org.simantics.db.WriteOnlyGraph" where
203     markUndoPoint :: () -> <WriteGraph> ()
204
205 importJava "org.simantics.db.WriteGraph" where
206     "Creates a new resource."
207     newResource :: () -> <WriteGraph> Resource
208     "Adds a statement to the semantic graph."
209     claim :: Resource -> Resource -> Resource -> <WriteGraph> ()
210     @JavaName claimLiteral
211     claimRelatedValue_ :: Resource -> Resource -> a -> Binding a -> <WriteGraph> ()
212     @JavaName claimLiteral
213     untypedClaimRelatedValue :: Resource -> Resource -> a -> <WriteGraph> ()
214     @JavaName claimValue
215     untypedClaimValue :: Resource -> a -> <WriteGraph> ()
216     @JavaName claimLiteral
217     claimRelatedValueWithType_ :: Resource -> Resource -> Resource -> a -> Binding a -> <WriteGraph> ()
218     "Removes a statement with the given subject, predicate and object"
219     deny :: Resource -> Resource -> Resource -> <WriteGraph> ()
220     @JavaName deny
221     denyByPredicate :: Resource -> Resource -> <WriteGraph> ()
222     @JavaName deny
223     denyAllStatements :: Resource -> <WriteGraph> ()
224     newClusterSet :: Resource -> <WriteGraph> ()
225     @JavaName denyValue
226     denyValue :: Resource -> <WriteGraph> ()
227
228 claimAssertion :: Resource -> Resource -> Resource -> <WriteGraph> ()
229 claimAssertion type_ predicate object = do
230     ass = newResource ()
231     claim ass L0.HasPredicate predicate
232     claim ass L0.HasObject object
233     claim type_ L0.Asserts ass
234
235 "Sets the value of the literal that is an object with the given subject and predicate."
236 @inline
237 claimRelatedValue :: Serializable a => Resource -> Resource -> a -> <WriteGraph> ()
238 claimRelatedValue s p v = claimRelatedValue_ s p v binding
239
240 @inline
241 claimRelatedValueWithType :: Serializable a => Resource -> Resource -> Resource -> a -> <WriteGraph> ()
242 claimRelatedValueWithType s p t v = claimRelatedValueWithType_ s p t v binding
243
244 importJava "org.simantics.layer0.utils.direct.GraphUtils" where
245     @JavaName getPossibleChild
246     possibleResourceChild :: Resource -> String -> <ReadGraph> (Maybe Resource)
247
248 @deprecated "Use function children instead."
249 resourceChildrenOf :: Resource -> <ReadGraph> [Resource]
250 resourceChildrenOf r = r # L0.ConsistsOf
251
252 importJava "org.simantics.db.common.utils.OrderedSetUtils" where
253     @JavaName add
254     addToOrderedSet :: Resource -> Resource -> <WriteGraph> Boolean
255     
256     @JavaName set
257     setOrderedSet :: Resource -> [Resource] -> <WriteGraph> Boolean
258     
259     @JavaName getSingleOwnerList
260     parentOrderedSet :: Resource -> <ReadGraph> Resource
261     
262     @JavaName toList
263     elementsOfOrderedSet :: Resource -> <ReadGraph> [Resource]
264     
265 importJava "org.simantics.db.common.utils.ListUtils" where
266     @JavaName toList
267     elementsOfList :: Resource -> <ReadGraph> [Resource]
268     
269     @JavaName create
270     createList :: [Resource] -> <WriteGraph> Resource
271
272     @JavaName create
273     createListWithType :: Resource -> [Resource] -> <WriteGraph> Resource
274     
275     @javaName insertBack
276     insertBack :: Resource -> [Resource] -> <WriteGraph> ()
277     
278     @javaName removeElement
279     removeElement :: Resource -> Resource -> <WriteGraph> Boolean
280     
281     @javaName swapWithPrevious
282     swapWithPrevious :: Resource -> Resource -> <WriteGraph> Boolean
283
284     @javaName swapWithNext
285     swapWithNext :: Resource -> Resource -> <WriteGraph> Boolean
286
287
288 importJava "org.simantics.db.common.utils.CommonDBUtils" where
289     isParent :: Resource -> Resource -> <ReadGraph> Boolean
290     possibleRelatedString :: Resource -> Resource -> <ReadGraph> Maybe String
291     possibleRelatedInteger :: Resource -> Resource -> <ReadGraph> Maybe Integer
292     objectsWithType :: Resource -> Resource -> Resource -> <ReadGraph> [Resource]
293     possibleObjectWithType :: Resource -> Resource -> Resource -> <ReadGraph> Maybe Resource
294
295 importJava "org.simantics.db.common.utils.NameUtils" where
296     findFreshName :: String -> Resource -> <ReadGraph> String
297     findFreshEscapedName :: String -> Resource -> <ReadGraph> String
298
299 "`subject # predicate` returns all objects with the given `subject` and `predicate`."
300 (#) :: Resource -> Resource -> <ReadGraph> [Resource]
301 subject # predicate = collectionToList $ objects_ subject predicate
302
303 "statements subject predicate` returns all statements with the given subject and predicate."
304 statements :: Resource -> Resource -> <ReadGraph> [Statement]
305 statements subject predicate = collectionToList $ statements_ subject predicate
306
307 importJava "org.simantics.scl.db.SCLFunctions" where
308     "Executes a read transaction and waits that it completes."
309     syncRead :: (() -> <Proc,ReadGraph> a) -> <Proc> a
310     "Executes a write transaction and waits that it completes."
311     syncWrite :: (() -> <Proc,ReadGraph,WriteGraph> a) -> <Proc> a
312     "Executes a delayed write transaction and waits that it completes."
313     delayedSyncWrite :: (() -> <Proc,WriteGraph> a) -> <Proc> a
314     
315     "Begins a read transaction and immediately returns."
316     asyncRead :: (() -> <Proc,ReadGraph> a) -> <Proc> ()
317     "Begins a write transaction and immediately returns."
318     asyncWrite :: (() -> <Proc,ReadGraph,WriteGraph> a) -> <Proc> ()
319     
320     virtualSyncWriteMem :: String -> (() -> <ReadGraph,WriteGraph> a) -> <WriteGraph> a
321     virtualSyncWriteWS :: String -> (() -> <ReadGraph,WriteGraph> a) -> <WriteGraph> a
322     
323     safeExec :: (() -> <Proc> a) -> <Proc> a
324     activateOnce :: Resource -> <Proc> ()
325     syncActivateOnce :: Resource -> <WriteGraph, Proc> ()
326     resourceFromId :: Long -> <ReadGraph> Resource
327     enableDependencies :: () -> <WriteGraph> ()
328     disableDependencies :: () -> <WriteGraph> ()
329     
330     unaryQuery :: (a -> <ReadGraph,e> b) -> a -> <ReadGraph> b
331     unaryQueryCached :: (a -> <ReadGraph,e> b) -> a -> <ReadGraph> b
332
333     "Makes a new read request with given procedure for calculating the result. The request is cached only if the current request is listened."
334     subquery :: (<ReadGraph,Proc> a) -> <ReadGraph,Proc> a
335     "Makes a new read request with given procedure for calculating the result. The request is always cached."
336     subqueryC :: (<ReadGraph,Proc> a) -> <ReadGraph,Proc> a
337     "Tries to convert the given Dynamic value to a value with the inferred type"
338     possibleFromDynamic :: Typeable a => String -> Dynamic -> Maybe a
339
340 importJava "org.simantics.db.layer0.util.Layer0Utils" where
341     undo :: () -> <Proc> String
342     undoOperations :: Integer -> <Proc> String
343     redo :: () -> <Proc> String
344     queryDebugSupport :: String -> <Proc> String
345     queryListSupport :: String -> <Proc> String
346     addCommentMetadata :: String -> <WriteGraph> ()
347     sortByCluster :: [a] -> (a->Resource) -> <ReadGraph> [a]
348     makeSynchronous :: Boolean -> <ReadGraph> ()
349     listOntologies :: () -> <ReadGraph> [Resource]
350     emptyTrashBin :: () -> <Proc> ()
351     purgeDatabase :: () -> <Proc> ()
352     prettyPrintResource :: Resource -> Boolean -> <ReadGraph> String
353
354     @private
355     @JavaName copyTo
356     copyTo_ :: Resource -> Resource -> <WriteGraph> Collection Resource
357     @JavaName getPossiblePredicateByName
358     possiblePredicateByName :: Resource -> String -> <ReadGraph> Maybe Resource
359
360 copyTo :: Resource -> Resource -> <WriteGraph> Resource
361 copyTo targetContainer source = do
362     (collectionToList $ copyTo_ targetContainer source)!0
363
364 importJava "org.simantics.db.common.utils.CommonDBUtils" where
365     selectClusterSet :: Resource -> <WriteGraph> () 
366
367 importJava "org.simantics.Simantics" where
368     @JavaName getProjectResource
369     currentProject :: () -> /*<Proc>*/ Resource
370
371 // Move to somewhere more generic module
372 importJava "java.util.Collection" where
373     data Collection a
374
375 importJava "java.util.ArrayList" where
376     @JavaName "<init>"
377     collectionToList :: Collection a -> [a]
378 /*@macro
379 collectionToList :: Collection a -> [a]
380 collectionToList x = Java.unsafeCoerce x
381 */ 
382
383 resourceToCollection :: a -> Collection a
384 resourceToCollection x = Java.unsafeCoerce x
385
386 newEntity :: [Resource -> <ReadGraph,WriteGraph> ()] -> <ReadGraph,WriteGraph> Resource
387 newEntity entitySpecs = do
388     entity = newResource ()
389     for entitySpecs (\spec -> spec entity)
390     entity
391
392 updateEntity :: Resource -> [Resource -> <ReadGraph,WriteGraph> ()] -> <ReadGraph,WriteGraph> Resource
393 updateEntity entity entitySpecs = do
394     for entitySpecs (\spec -> spec entity)
395     entity
396
397 hasStatement predicate object entity = 
398     claim entity predicate object
399 hasProperty relation value entity = 
400     claimRelatedValue entity relation value
401 hasPossibleProperty relation value entity =
402     match value with
403       Just v -> claimRelatedValue entity relation v
404       Nothing -> ()
405 hasTypedProperty relation value t entity = 
406     claimRelatedValueWithType entity relation t value        
407 hasName (n :: String) = hasProperty L0.HasName n
408 hasLabel (l :: String) = hasProperty L0.HasLabel l
409 hasType t = hasStatement L0.InstanceOf t
410 hasParent p = hasStatement L0.PartOf p
411
412 importJava "org.simantics.databoard.util.URIStringUtils" where
413     @JavaName splitURISCL
414     splitURI :: String -> [String]
415     @JavaName escape
416     escapeURI :: String -> String
417     @JavaName unescape
418     unescapeURI :: String -> String
419
420 @private
421 importJava "org.simantics.db.layer0.request.ActiveModels" where
422     @JavaName getPossibleActiveModel
423     activeModel :: Resource -> <ReadGraph> Maybe Resource
424
425 "Gives the current active model."
426 currentModel :: <ReadGraph> Resource
427 currentModel = match activeModel (currentProject ()) with
428     Just model -> model
429     Nothing -> fail "No active model."
430
431 "Gives the current active model if it exists or Nothing otherwise."
432 possibleCurrentModel :: <ReadGraph> Maybe Resource
433 possibleCurrentModel = activeModel (currentProject ())
434     
435 startUndoPoint :: String -> <WriteGraph> ()
436 startUndoPoint string = do
437     markUndoPoint ()
438     addCommentMetadata (string)
439     ()
440
441 @inline
442 lift1Read :: (a -> <ReadGraph,Proc> b) -> (a -> <Proc> b)
443 lift1Read f x = syncRead (\_ -> f x)
444
445 @inline
446 lift2Read :: (a -> b -> <ReadGraph,Proc> c) -> (a -> b -> <Proc> c)
447 lift2Read f x y = syncRead (\_ -> f x y)
448
449 @inline
450 lift3Read :: (a -> b -> c -> <ReadGraph,Proc> d) -> (a -> b -> c -> <Proc> d)
451 lift3Read f x y z = syncRead (\_ -> f x y z)
452
453 @inline
454 lift1Write :: (a -> <WriteGraph,Proc> b) -> (a -> <Proc> b)
455 lift1Write f x = syncWrite (\_ -> f x)
456
457 @inline
458 lift2Write :: (a -> b -> <WriteGraph,Proc> c) -> (a -> b -> <Proc> c)
459 lift2Write f x y = syncWrite (\_ -> f x y)
460
461 @inline
462 lift3Write :: (a -> b -> c -> <WriteGraph,Proc> d) -> (a -> b -> c -> <Proc> d)
463 lift3Write f x y z = syncWrite (\_ -> f x y z)
464
465 """
466 Returns a child Browsable of the specified parent that has that is the child
467 of the specified parent with the specified name path.
468 """
469 childWithPath :: Browsable a => a -> [String] -> <ReadGraph> a
470 childWithPath parent path = 
471     foldl (\r name -> match possibleChild r name with
472               Just c -> c
473               Nothing -> fail ("Didn't find " + name + ".") 
474           ) 
475           parent path
476
477 """
478 Like `childWithPath` but returns Maybe a which will be `Nothing` if no child
479 was found.
480 """
481 possibleChildWithPath :: Browsable a => a -> [String] -> <ReadGraph> Maybe a
482 possibleChildWithPath parent path = 
483     foldl (\r name -> match r with
484               Just c -> possibleChild c name
485               Nothing -> Nothing 
486           ) 
487           (Just parent) path