blob: 55a677db14ea7441333297a4d6fb45ca35b7c061 [file] [log] [blame]
/**
* Backbone model denoting the remote Fuseki server.
*/
define(
function( require ) {
"use strict";
var Marionette = require( "marionette" ),
Backbone = require( "backbone" ),
_ = require( "underscore" ),
fui = require( "app/fui" ),
sprintf = require( "sprintf" ),
Task = require( "app/models/task" );
/**
* This model represents the core representation of the remote Fuseki
* server. Individual datasets have their own model.
*/
var Dataset = Backbone.Model.extend( {
initialize: function( datasetDescription, baseURL, mgmtURL ) {
this.set( datasetDescription );
this.set( {
baseURL: baseURL,
mgmtURL: mgmtURL,
counts: {},
countPerformed: false,
counting: false,
statistics: false
} );
},
/* x is the empty object if baseURL is ""
* Ensure it is always a string.
*/
getStr: function(key) {
var x = this.get( key );
return jQuery.isEmptyObject(x) ? "" : x ;
},
baseURL: function() {
return this.getStr( "baseURL" );
},
mgmtURL: function() {
return this.getStr( "mgmtURL" );
},
mgmtActionURL: function() {
return this.get( "mgmtURL" ) + this.name();
},
statisticsURL: function() {
return sprintf( "%s/$/stats%s", this.baseURL(), this.name() );
},
name: function() {
return this.get( "ds.name" );
},
services: function() {
return this.get( "ds.services" );
},
countPerformed: function() {
return this.get( "countPerformed" );
},
counts: function() {
return this.get( "counts" );
},
serviceTypes: function() {
return _.map( this.services(), function( s ) {return s["srv.type"];} );
},
/** Return a descriptive data-structure listing all this datasets services */
servicesDescription: function() {
var description = [];
var self = this;
_.each( this.services(), function( s ) {
_.each( s["srv.endpoints"], function( e ) {
description.push( {label: s["srv.description"],
url: self.datasetEndpointURL( e )
} );
} );
} );
description.sort( function( d0, d1 ) {
return (d0.label < d1.label) ? -1 : (d0.label > d1.label ? 1 : 0);
} );
return description;
},
/** Return the first service that has the given type */
serviceOfType: function( serviceType ) {
return _.find( this.services(), function( s ) {
return s["srv.type"] === serviceType;
} );
},
/** Return the first endpoint of the first service that has the given type */
endpointOfType: function( serviceType ) {
var service = this.serviceOfType( serviceType );
if ( ! service )
return null;
var x = service["srv.endpoints"];
x = x.filter(function(v){return v!==''});
var ep = _.first(x);
return ep;
/* return service && _.first( service["srv.endpoints"] );*/
},
/* Return URL for a service of a given type or null, if no such service */
endpointURL: function( serviceType ) {
var endpoint = this.endpointOfType( serviceType );
return endpoint ? this.datasetEndpointURL( endpoint ) : null;
},
/** Return the URL for the given endpoint */
datasetEndpointURL: function( endpoint ) {
return sprintf( "%s%s/%s", this.baseURL(), this.name(), endpoint );
},
/** Return the sparql query URL for this dataset, if it has one, or null */
queryURL: function() {
return this.endpointURL( "query" ) ;
},
/** Return the sparql update URL for this dataset, if it has one, or null */
updateURL: function() {
return this.endpointURL( "update" ) ;
},
/** Return the GSP write URL for this dataset, if it has one, or null */
graphStoreProtocolURL: function() {
return this.endpointURL( "gsp-rw" ) ;
},
/** Return the GSP read URL for this dataset, if it has one, or null */
graphStoreProtocolReadURL: function() {
return this.endpointURL( "gsp-r" ) ;
},
/** Return the upload URL for this dataset, if it has one, or null */
uploadURL: function( graphName ) {
if (this.graphStoreProtocolURL() !== null) {
return sprintf( "%s%s", this.graphStoreProtocolURL(), (graphName === "default" ? "" : ("?graph=" + graphName) ));
}
else {
return null;
}
},
/** Perform the action to delete the dataset. Returns the Ajax deferred object */
deleteDataset: function() {
return $.ajax( {
url: this.mgmtActionURL(),
type: 'DELETE'
} );
},
/** Perform the action of taking a backup of this dataset */
backupDataset: function() {
var backupURL = sprintf( "%s/$/backup%s", this.baseURL(), this.name() );
var ds = this;
return $.ajax( {
url: backupURL,
type: 'POST'
} )
.done( function( taskDescription ) {
new Task( ds, "backup", taskDescription );
} );
},
/**
* Request the statistics for this dataset, and return the promise object for the callback.
* @param keep If truthy, and we have existing statistics, re-use the existing stats
* */
statistics: function( keep ) {
var self = this;
var currentStats = this.get( "statistics" );
if (currentStats && keep) {
return $.Deferred().resolveWith( null, currentStats );
}
else {
return $.getJSON( this.statisticsURL() )
.then( function( data ) {
self.set( "statistics", data );
return data;
} );
}
},
/** Perform a count query to determine the size of the dataset. Changes the size property when done,
* but also returns the JQuery promise object used to monitor the query response */
count: function() {
var self = this;
var query1 = sprintf( "select (count(*) as ?count) {?s ?p ?o}" );
var query2 = sprintf( "select ?g (count(*) as ?count) {graph ?g {?s ?p ?o}} group by ?g" );
self.set( "counting", true );
var updateCount = function( model, result, graph ) {
var n = parseInt( result.count.value );
var counts = _.extend( {}, model.get( "counts" ) );
counts[graph] = n;
model.set( "counts", counts );
};
$.getJSON( self.queryURL(), { query: query1 } )
.done( function( data ) {
updateCount( self, data.results.bindings[0], "default graph" );
$.getJSON( self.queryURL(), { query: query2 } )
.done( function( data ) {
_.each( data.results.bindings, function( binding ) {
if (binding.g) {
updateCount( self, binding, binding.g.value );
}
} );
} );
self.set( {countPerformed: true, counting: false} );
} );
},
/**
* Fetch the content of the given graph as Turtle. Return the jQuery promise
* object for the Ajax call.
*/
fetchGraph: function( graphName ) {
return $.ajax( this.graphStoreProtocolReadURL(),
{method: "get",
headers: {Accept : "text/turtle; charset=utf-8"},
dataType: "html",
data: {graph: graphName}
} );
},
/**
* Put the given Turtle content back to the server using the given graph name
*/
putGraph: function( turtle, graphName ) {
return $.ajax( sprintf( "%s?graph=%s", this.graphStoreProtocolURL(), graphName ),
{method: "put",
dataType: "json",
data: turtle,
contentType: "text/turtle; charset=uft-8"
} );
}
} );
return Dataset;
}
);