From: Roel Janssen <roel@gnu.org>
To: Amirouche Boubekki <amirouche@hypermove.net>
Cc: Guile User <guile-user@gnu.org>
Subject: Re: neon: git for structured data [Was: Functional database]
Date: Wed, 21 Feb 2018 17:02:07 +0100 [thread overview]
Message-ID: <87po4yuy9s.fsf@gnu.org> (raw)
In-Reply-To: <3bf20807996ce0bdc4e5ca6ea1d3776f@hypermove.net>
[-- Attachment #1: rdf.scm --]
[-- Type: application/octet-stream, Size: 13033 bytes --]
;;; Copyright © 2018 Roel Janssen <roel@gnu.org>
;;;
;;; This program is free software: you can redistribute it and/or
;;; modify it under the terms of the GNU General Public License
;;; as published by the Free Software Foundation, either version 3 of
;;; the License, or (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;;; Affero General Public License for more details.
;;;
;;; You should have received a copy of the GNU Affero General Public
;;; License along with this program. If not, see
;;; <http://www.gnu.org/licenses/>.
;;
;; This is an interface to raptor2 and librdf. See http://www.librdf.org
;; for the API documentation.
;;
;; Some wrapping has been done:
;; - The *-free functions reset the argument's pointer to 0x0.
;; - String arguments are converted to pointer using pointer->string,
;; so that regular strings in Scheme can be used as C-string inputs.
;;
(define-module (redland rdf)
#:use-module (system foreign)
#:export (rdf-link-library
rdf-unlink-library
rdf-world-new
rdf-world-open
rdf-world-free
rdf-world-get-raptor
raptor-world-open
raptor-world-free
raptor-new-iostream-from-file-handle
raptor-new-iostream-from-filename
raptor-iostream-free
rdf-storage-new
rdf-storage-free
rdf-storage-open
rdf-storage-close
rdf-storage-size
rdf-model-new
rdf-model-free
rdf-model-transaction-start
rdf-model-transaction-commit
rdf-model-transaction-rollback
rdf-model-write
rdf-model-add
rdf-model-size
rdf-model-add-statement
rdf-statement-new-from-nodes
rdf-statement-free
rdf-uri-new
rdf-uri-free
rdf-node-new-from-uri-local-name
rdf-serializer-new
rdf-serializer-free
rdf-serializer-serialize-model-to-file
rdf-serializer-serialize-model-to-string))
;;
;; LIBRARY HANDLE
;; ----------------------------------------------------------------------------
;; TODO: Integrate this with the build system.
(define %library-path "/home/roel/.guix-profile/lib")
(define %rdf-handle %null-pointer)
(define %raptor-handle %null-pointer)
(define (rdf-link-library)
(set! %rdf-handle (dynamic-link (string-append %library-path "/librdf")))
(set! %raptor-handle (dynamic-link (string-append %library-path "/libraptor2")))
(and (dynamic-object? %rdf-handle)
(dynamic-object? %raptor-handle)))
(define (rdf-unlink-library)
(dynamic-unlink %rdf-handle)
(dynamic-unlink %raptor-handle))
(rdf-link-library)
;;
;; CONVENIENCE
;; ----------------------------------------------------------------------------
(define-syntax-rule
(define-foreign-function symbol handle return-type c-function args)
(define symbol
(pointer->procedure return-type (dynamic-func c-function handle) args)))
;;
;; WORLD FUNCTIONS
;; ----------------------------------------------------------------------------
;; Returns a newly allocated librdf_world object.
(define-foreign-function rdf-world-new
%rdf-handle '* "librdf_new_world" '())
;; Opens a whole new world.
(define-foreign-function rdf-world-open
%rdf-handle void "librdf_world_open" '(*))
;; Deallocates memory of the world. This function takes one argument: A
;; librdf_world object.
(define-foreign-function rdf-world-free-raw
%rdf-handle void "librdf_free_world" '(*))
(define-syntax-rule
(rdf-world-free world)
(begin
(rdf-world-free-raw world)
(set! world %null-pointer)))
;; Takes two arguments: librdf_world, and raptor_world.
(define-foreign-function rdf-world-set-raptor
%rdf-handle void "librdf_world_set_raptor" '(* *))
;; Returns a raptor_world object for the specified librdf_world object.
(define-foreign-function rdf-world-get-raptor
%rdf-handle '* "librdf_world_get_raptor" '(*))
;;
;; RAPTOR FUNCTIONS
;; ----------------------------------------------------------------------------
;(define raptor-world-new
; (pointer->procedure '* (dynamic-func "raptor_new_world" %raptor-handle) '()))
(define-foreign-function raptor-world-free-raw
%raptor-handle void "raptor_free_world" '())
(define-syntax-rule
(raptor-world-free raptor)
(begin
(raptor-world-free-raw raptor)
(set! raptor %null-pointer)))
;; Returns a raptor_iostream object. Takes a raptor_world object, and a
;; FILE pointer.
(define-foreign-function raptor-new-iostream-from-file-handle
%raptor-handle '* "raptor_new_iostream_from_file_handle" '(* *))
;; Returns a raptor_iostream object. Takes a raptor_world object, and a
;; filename (string).
(define-foreign-function raptor-new-iostream-from-filename-raw
%raptor-handle '* "raptor_new_iostream_from_filename" '(* *))
(define-syntax-rule
(raptor-new-iostream-from-filename world filename)
(raptor-new-iostream-from-filename-raw world (string->pointer filename)))
(define-foreign-function raptor-world-open
%raptor-handle int "raptor_world_open" '(*))
(define-foreign-function raptor-world-free
%raptor-handle void "raptor_free_world" '(*))
(define-foreign-function raptor-iostream-free
%raptor-handle void "raptor_free_iostream" '(*))
;;
;; STORAGE FUNCTIONS
;; ----------------------------------------------------------------------------
;; Returns a newly allocated librdf_storage object. This function takes four
;; arguments: A world object, storage name (string), name (string), and options
;; (string).
(define-foreign-function rdf-storage-new-raw
%rdf-handle '* "librdf_new_storage" '(* * * *))
(define-syntax-rule
(rdf-storage-new world storage-name name options)
(rdf-storage-new-raw world
(string->pointer storage-name)
(string->pointer name)
(if (eq? options %null-pointer)
options
(string->pointer options))))
;; Deallocates memory of a librdf_storage object. This function takes one
;; argument: A librdf_storage object.
(define-foreign-function rdf-storage-free-raw
%rdf-handle void "librdf_free_storage" '(*))
(define-syntax-rule
(rdf-storage-free storage)
(begin
(rdf-storage-free-raw storage)
(set! storage %null-pointer)))
(define-foreign-function rdf-storage-size-raw
%rdf-handle int "librdf_storage_size" '(*))
(define-syntax-rule
(rdf-storage-size storage)
(let ((size (rdf-storage-size-raw storage)))
(if (< size 0)
(if #f #t) ; Returns #<unspecified>
size)))
;; Takes two arguments: librdf_storage, and librdf_model.
(define-foreign-function rdf-storage-open-raw
%rdf-handle int "librdf_storage_open" '(* *))
(define-syntax-rule
(rdf-storage-open storage model)
(eq? (rdf-storage-open-raw storage model) 0))
(define-foreign-function rdf-storage-close-raw
%rdf-handle int "librdf_storage_close" '(*))
(define-syntax-rule
(rdf-storage-close storage)
(begin
(rdf-storage-close-raw storage)
(set! storage %null-pointer)))
;;
;; MODEL FUNCTIONS
;; ----------------------------------------------------------------------------
;; Returns a newly allocated librdf_model object. This function takes three
;; arguments: A librdf_world object, a librdf_storage object, and an options
;; string.
(define-foreign-function rdf-model-new-raw
%rdf-handle '* "librdf_new_model" '(* * *))
(define-syntax-rule
(rdf-model-new world storage options)
(rdf-model-new-raw world storage
(if (eq? options %null-pointer)
options
(string->pointer options))))
;; Deallocates memory of a librdf_model object. This function takes one
;; argument: A librdf_model object.
(define-foreign-function rdf-model-free-raw
%rdf-handle void "librdf_free_model" '(*))
(define-syntax-rule
(rdf-model-free model)
(begin
(rdf-model-free-raw model)
(set! model %null-pointer)))
;; Starts a transaction on a librdf_model object. This function takes one
;; argument: A librdf_model object.
(define-foreign-function rdf-model-transaction-start
%rdf-handle int "librdf_model_transaction_start" '(*))
;; Commits a transaction on a librdf_model object. This function takes one
;; argument: A librdf_model object.
(define-foreign-function rdf-model-transaction-commit
%rdf-handle int "librdf_model_transaction_start" '(*))
;; Rolls a transaction back on a librdf_model object. This function takes one
;; argument: A librdf_model object.
(define-foreign-function rdf-model-transaction-rollback
%rdf-handle int "librdf_model_transaction_start" '(*))
;; Writes a librdf_model object to a raptor_iostream.
(define-foreign-function rdf-model-write
%rdf-handle int "librdf_model_write" '(* *))
;; Adds a triplet to an librdf_model object. This function takes four
;; arguments: A librdf_model object, and three librdf_node objects.
(define-foreign-function rdf-model-add
%rdf-handle int "librdf_model_add" '(* * * *))
(define-foreign-function rdf-model-size-raw
%rdf-handle int "librdf_model_size" '(*))
(define-syntax-rule
(rdf-model-size model)
(let ((size (rdf-model-size-raw model)))
(if (< size 0)
(if #f #t) ; Returns #<unspecified>
size)))
(define-foreign-function rdf-model-add-statement
%rdf-handle int "librdf_model_add_statement" '(* *))
;;
;; STATEMENT FUNCTIONS
;; ----------------------------------------------------------------------------
(define-foreign-function rdf-statement-new-from-nodes
%rdf-handle '* "librdf_new_statement_from_nodes" '(* * * *))
;; Deallocates memory of a librdf_statement object. This function takes one
;; argument: A librdf_statement object.
(define-foreign-function rdf-statement-free-raw
%rdf-handle void "librdf_free_statement" '(*))
(define-syntax-rule
(rdf-statement-free statement)
(begin
(rdf-statement-free-raw statement)
(set! statement %null-pointer)))
;;
;; URI FUNCTIONS
;; ----------------------------------------------------------------------------
;; Returns a newly allocated librdf_uri object. This function takes two
;; arguments: A librdf_world object, and a URI (string).
(define-foreign-function rdf-uri-new-raw
%rdf-handle '* "librdf_new_uri" '(* *))
(define-syntax-rule
(rdf-uri-new world uri)
(rdf-uri-new-raw world (string->pointer uri)))
;; Deallocates memory of a librdf_uri object. This function takes one
;; argument: A librdf_uri object.
(define-foreign-function rdf-uri-free-raw
%rdf-handle void "librdf_free_uri" '(*))
(define-syntax-rule
(rdf-uri-free uri)
(begin
(rdf-uri-free-raw uri)
(set! uri %null-pointer)))
;;
;; NODE FUNCTIONS
;; ----------------------------------------------------------------------------
;; This function takes three arguments: A librdf_world object,
;; a librdf_uri object, and string.
(define-foreign-function rdf-node-new-from-uri-local-name-raw
%rdf-handle '* "librdf_new_node_from_uri_local_name" '(* * *))
(define-syntax-rule
(rdf-node-new-from-uri-local-name world uri local-name)
(rdf-node-new-from-uri-local-name-raw world uri (string->pointer local-name)))
;;
;; SERIALIZER FUNCTIONS
;; ----------------------------------------------------------------------------
;; Arguments: librdf_world*, name (string), mime_type (string), librdf_uri*.
;; Returns: librdf_serializer*
(define-foreign-function rdf-serializer-new-raw
%rdf-handle '* "librdf_new_serializer" '(* * * *))
(define-syntax-rule
(rdf-serializer-new world name mime-type uri)
(rdf-serializer-new-raw world (if (eq? %null-pointer name)
name
(string->pointer name))
(if (eq? %null-pointer mime-type)
mime-type
(string->pointer mime-type)) uri))
;; Arguments: librdf_serializer*
(define-foreign-function rdf-serializer-free-raw
%rdf-handle void "librdf_free_serializer" '(*))
(define-syntax-rule
(rdf-serializer-free serializer)
(begin
(rdf-serializer-free-raw serializer)
(set! serializer %null-pointer)))
;; Arguments: librdf_serializer, name (string), librdf_uri, librdf_model.
;; Returns: integer
(define-foreign-function rdf-serializer-serialize-model-to-file-raw
%rdf-handle int "librdf_serializer_serialize_model_to_file" '(* * * *))
(define-syntax-rule
(rdf-serializer-serialize-model-to-file a b c d)
(rdf-serializer-serialize-model-to-file-raw a (string->pointer b) c d))
;; Arguments: librdf_serializer, librdf_uri, librdf_model.
;; Returns: unsigned char (string)
(define-foreign-function rdf-serializer-serialize-model-to-string
%rdf-handle '* "librdf_serializer_serialize_model_to_string" '(* * *))
[-- Attachment #2: Type: text/plain, Size: 4288 bytes --]
Dear Amirouche,
I'm not exactly sure if this fits in with your plans, but nevertheless
I'd like to share this code with you.
I recently looked into using triple stores (actually quad stores)
and wrote an interface to Redland librdf for Guile.
I attached the source code of the interface.
With this interface, you can write something like this:
--8<---------------cut here---------------start------------->8---
(use-modules (redland rdf) ; The attached module.
(system foreign))
(define world (rdf-world-new))
(rdf-world-open world)
(define store (rdf-storage-new
world
"hashes"
"redland"
"new=true,hash-type='bdb',dir='path/to/triplestore'"))
(define model (rdf-model-new world store %null-pointer))
(define local-uri (rdf-uri-new world "http://localhost:5000/Redland/"))
(define s (rdf-node-new-from-uri-local-name world local-uri "Test"))
(define p (rdf-node-new-from-uri-local-name world local-uri "TestPredicate"))
(define o (rdf-node-new-from-uri-local-name world local-uri "TestObject"))
(define statement (rdf-statement-new-from-nodes world s p o))
(rdf-model-add-statement model statement)
(rdf-statement-free statement)
(rdf-model-size model)
(rdf-storage-size store)
;; Example mime-type: application/rdf+xml
(define serializer (rdf-serializer-new world %null-pointer "text/turtle" %null-pointer))
(define serialized (rdf-serializer-serialize-model-to-string serializer local-uri model))
(format #t "Serialized: ~s~%" (pointer->string serialized))
(rdf-uri-free local-uri)
(rdf-model-free model)
(rdf-storage-free store)
(rdf-world-free world)
--8<---------------cut here---------------end--------------->8---
Kind regards,
Roel Janssen
Amirouche Boubekki writes:
> I tried chez scheme and I think GNU Guile
> is a better platform for what I am trying
> to achieve, so I am back.
>
> I also know better what I want to achieve.
> I will create a triple store that comply
> with semantic web standard that is
> a RDF triple store. At [0] and [1] you will
> find a primer on what is RDF in the former
> and the concepts in the latter.
>
> [0] https://www.w3.org/TR/rdf11-primer/
> [1] https://www.w3.org/TR/rdf11-concepts/
>
> It will also be branch-able etc... like git.
>
> Also, I also plan to implement sparql.
> If you find sparql difficult I recommend
> the tutorial at data.world [2] in the mean time.
> It's not very difficult and looks like SQL.
> Hence I also plan to implement sparql [3].
>
> [2] https://docs.data.world/tutorials/sparql/
> [3] https://www.w3.org/TR/sparql11-overview/
>
> What I want to do is something similar to data.world,
> that is a gitlab-like platform for data and replace
> the use of git in projects like datahub.io [4].
>
> [4] http://datahub.io/core/registry
>
> Enough talking, what is the status? Well I finished
> porting what I had in chez and can now run the following
> scenario:
>
> - In master branch, I commit two triples
>
> - In other branch, that is orphan branch, I commit
> two triples among where one of them overlaps with
> master.
>
> - I can query both branch
>
> - In a merge commit, I fix the conflict between both
> branch.
>
> - I can query the resulting branch and get the expected
> result.
>
> The code might be easier to read [5]
>
> [5] https://github.com/amirouche/neon/blob/master/guile/neon.scm
>
> What is missing, in order of difficulty:
>
> - microkanren package
> https://framagit.org/a-guile-mind/microkanren
>
> - wiredtiger 3 package
>
> - Turtle aka. .ttl format parser https://www.w3.org/TR/turtle/
>
> - sparql queries parser https://www.w3.org/TR/rdf-sparql-query/
>
> - I am not sure of the status of guile-squee yet
> https://notabug.org/cwebber/guile-squee/
>
> - pluggable backends
>
> If you want to work one of this item, send me an email.
>
> What I plan to work on next:
>
> There is a semantic difference between neon
> and RDF triple stores. In a triple store you
> can have as many times as you want the same
> attribute given a subject. That is (ref subject)
> doesn't return a proper alist.
>
> There is two other links that remain to be cited
>
> - https://www.w3.org/TR/rdf11-mt/
>
> - https://www.w3.org/TR/2014/NOTE-rdf11-datasets-20140225/
>
> Happy hacking,
next prev parent reply other threads:[~2018-02-21 16:02 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-21 14:49 neon: git for structured data [Was: Functional database] Amirouche Boubekki
2018-02-21 16:02 ` Roel Janssen [this message]
2018-02-21 18:41 ` amirouche
2018-03-05 22:32 ` amirouche
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87po4yuy9s.fsf@gnu.org \
--to=roel@gnu.org \
--cc=amirouche@hypermove.net \
--cc=guile-user@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).