Lurch
Lurch

Reputation: 137

How to store SVGs in OrientDB using OrientJS

My webapp needs to include the feature to save SVG files to the database so that they can be fetched and rendered in the browser with the ability to make use of CSS to style parts of the image based on parsing the XML. Storing as base64 does not do the job, because then it is rendered to the DOM without making the XML available for parsing and manipulation.

The docs on working with binary files in orientjs are extremely thin, and I cannot find any suitable examples out there, so I'm pretty much stuck.

Any help would be appreciated.

Upvotes: 1

Views: 99

Answers (1)

Jean-Paul
Jean-Paul

Reputation: 21150

An svg is nothing else but a string of XML syntax.

E.g. consider the following svg:

var svg = `<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
  <circle cx="100" cy="100" r="50" stroke="black" stroke-width="5" fill="red" /></svg>`

You pretty much have two options:

  1. Store the svg as a simple String
  2. Store the svg as a base64 encoded String

If your svg only contains ASCII characters, method 1 should be fine. Otherwise you need to use method 2. Note: method 2 can be used to store any type of file!!!

An example of both methods in OrientJS:

// First npm install the following packages
npm install orientjs
npm install await-to-js

Then create a file app.js and run it:

const OrientDBClient = require("orientjs").OrientDBClient;
const to = require('await-to-js').default;

// SVG EXAMPLE IMAGE
var svg = `<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
<circle cx="100" cy="100" r="50" stroke="black" stroke-width="5" fill="red" /></svg>`

connect().then(async function(db) {

    // Add class to database
    [err, result] = await to(
        db.session.class.create('Example', 'V')
    );
    if (err) { console.error(err); };

    // Add property image to class
    [err, result] = await to(
        db.session.command('CREATE PROPERTY Example.image STRING').all()
    );
    if (err) { console.error(err); };

    // Add property name to class
    [err, result] = await to(
        db.session.command('CREATE PROPERTY Example.type STRING').all()
    );
    if (err) { console.error(err); };

    // *****************************************************************
    // ********************** USING PLAIN STRING ***********************
    // *****************************************************************

    // Add node to class with image stored as plain string (just use var [svg])
    [err, result] = await to(
        db.session.insert().into('Example').set({image: svg, type: 'string'}).one()
    );
    if (err) { console.error(err); };

    // Retrieve simple string from database
    [err, result] = await to(
        db.session.select('image').from('Example').where({type: 'string'}).one()
    );
    if (err) { console.error(err); };
    // Output svg XML to the console
    console.log(result.image);

    // *****************************************************************
    // ********************* USING BASE64 ENCODING *********************
    // *****************************************************************

    // Convert to base64
    var buf = Buffer.from(svg, 'utf-8').toString("base64");

    // Add node to class with image encoded as base64
    [err, result] = await to(
        db.session.insert().into('Example').set({image: buf, type: 'base64'}).one()
    );
    if (err) { console.error(err); };

    // Retrieve base64 encoded svg from database
    [err, result] = await to(
        db.session.select('image').from('Example').where({type: 'base64'}).one()
    );
    if (err) { console.error(err); };

    // Output svg XML to the console
    var output = Buffer.from(result.image, 'base64');
    console.log(output.toString('ascii'));
})

async function connect() {
    // Connect to Server
    [err,client] = await to(OrientDBClient.connect({
        host:   'localhost',    // Specify your host here
        port:   '2424'          // Make sure you call the HTTP port
    }));
    if (err) {
        console.log("Cannot reach OrientDB. Server is offline");
        return false;
    }

    // Connect to Database.
    [err,session] = await to(client.session({ 
        name:       'demodb',   // Name of your database
        username:   'admin',    // Username of your database
        password:   'admin'     // Password of your database
    }));
    if (err) {
        console.log("Database doesn't exist.");
        return false;
    }

    // Add handler
    session.on('beginQuery', (obj) => {
        console.log(obj);
    });

    // Check if session opens
    console.log("Successfully connected to database.");
    var graph = {client, session};
    return graph;
}

This code will create a class Example that has properties image and type and will then create two vertices: one where the svg is saved as a string and one where the svg is saved as a base64 encoded string. It also shows how to retrieve both images again into javascript.

After you've retrieved the files, you can then pass them to your front-end and render them on the DOM, at which point any CSS styles that are defined on the DOM will also be applied.

I hope that answers your question.

Upvotes: 0

Related Questions