<<

TIBCO® Graph Database Getting Started Guide Version 3.0 November 2020

Copyright © 2020. TIBCO Software Inc. All Rights Reserved. 2

Contents

Figures ...... 3 TIBCO Documentation and Support Services ...... 4 Overview ...... 5 Editions of TIBCO Graph Database ...... 5 Installing Graph Database ...... 6 Graph Database Folder Structure ...... 7 Configuring Graph Database ...... 8 File Information ...... 8 initdb.conf ...... 8 tgdb.conf ...... 8 tgsec.conf ...... 9 Graph Database Server Commands and Controls ...... 10 Graph Database Admin Console ...... 11 Graph Database Client ...... 12 Hands-on Exercise ...... 13 Initializing the Database ...... 14 Starting the Database Server ...... 15 Defining the Metadata in the Admin Console ...... 15 Building the ...... 16 Searching for a Member of the House ...... 20 Updating a Member of the House ...... 22 Legal and Third-Party Notices ...... 26

TIBCO® Graph Database Getting Started Guide 3

Figures

House of Bonaparte - (Partial) ...... 13

TIBCO® Graph Database Getting Started Guide 4

TIBCO Documentation and Support Services

How to Access TIBCO Documentation

Documentation for TIBCO products is available on the TIBCO Product Documentation website, mainly in HTML and PDF formats. The TIBCO Product Documentation website is updated frequently and is more current than any other documentation included with the product. To access the latest documentation, visit https://docs.tibco.com.

Product-Specific Documentation

Documentation for TIBCO Graph Database is available on https://docs.tibco.com/products/tibco-graph- database-enterprise-edition-3-0-0 page. This feature is available to both Enterprise edition and Community. The guidelines specified for Clustering is applicable only to Enterprise edition. The following documents form the documentation set:

● TIBCO® Graph Database Getting Started: Read this manual before reading any other manual in the documentation set. This manual describes the terminology and concepts of the platform. The other manuals in the documentation set assume you are familiar with the information in this manual.

● TIBCO Graph Database Administration : Read this manual to learn how to manage the runtime and deploy and manage applications.

● TIBCO® Graph Database Security Guidelines: Read this manual to learn more about security guidelines and recommendations for TIBCO® Graph Database.

● TIBCO Graph Database Release Notes: Read this manual for a list of new and changed features, steps for migrating from a previous release, and lists of known issues and closed issues for the release.

How to Contact TIBCO Support

You can contact TIBCO Support in the following ways:

● For an overview of TIBCO Support, visit http://www.tibco.com/services/support.

● For accessing the Support Knowledge Base and getting personalized content about products you are interested in, visit the TIBCO Support portal at https://support.tibco.com.

● For creating a Support case, you must have a valid maintenance or support contract with TIBCO. You also need a user name and password to log in to https://support.tibco.com. If you do not have a user name, you can request one by clicking Register on the website.

How to Join TIBCO Community

TIBCO Community is the official channel for TIBCO customers, partners, and employee subject matter experts to share and access their collective experience. TIBCO Community offers access to Q&A forums, product wikis, and best practices. It also offers access to extensions, adapters, solution accelerators, and tools that extend and enable customers to gain full value from TIBCO products. In addition, users can submit and vote on feature requests from within the TIBCO Ideas Portal. For a free registration, go to https://community.tibco.com.

TIBCO® Graph Database Getting Started Guide 5

Overview

TIBCO Graph Database is a translytical database that delivers a complex web of dynamic data into analytical relationships at the speed of transactions. A graph represents a set of objects, which are called nodes, and the connections between these nodes, which are called edges. Edges can be unidirectional (directed from one node to another node) or bidirectional (directed from one node to another and vice versa), or undirected. A single graph can hold multiple types of nodes. Example: A graph named GRAPH 1 can have two nodes, one node of type PERSON and one node of type BUSINESS. The value for node type PERSON can be John Doe and the value of the node type BUSINESS can be Example Corporation. A single node, within a graph, can have one or more edges. Example: In the graph named GRAPH 1, a node of type PERSON can have an edge with another node of type PERSON, and can also have an edge with another node of type BUSINESS. If the value of one node of type PERSON is John Doe and if the value of another node of type PERSON is Jane Doe, an edge between these two nodes can mean that these two people know each other. Similarly if there is an edge John Doe and Example Corporation, it means that John Doe is a patron of Example Corporation. A graph database is a database that also offers the persistent storage of its data as nodes and edges, so that a graph algorithm can be utilized to traverse the nodes. The benefits of TIBCO Graph Database are as follows:

● Flexible Schema - Assumes objects and nodes are linked by relationships; designed to constantly evolve, without impacting performance of existing queries and app functionality.

● Consistent Performance - Index-free adjacency negates the requirement for index lookups; enables query performance to remain relatively consistent, even as data sets grow.

● Increased Value - Enables quick extraction of new insight from large and complex databases. It also helps uncover unknown interactions and relationships and provides valuable insight into semantic context. Editions of TIBCO Graph Database There are two editions of TIBCO Graph Database: Community Edition and Enterprise Edition. The comparison between the editions are as follows:

Particulars Community Edition Enterprise Edition

Location https://community.tibco.com https://edelivery.tibco.com

Memory 4 GB to 16 GB 4 GB to 1 TB

Users 5 Unlimited

Connections 10 Unlimited

Storage 100 GB 256 TB

TIBCO® Graph Database Getting Started Guide 6

Installing Graph Database

To install TIBCO Graph Database, see the ReadMe file for the hardware and software requirements. Perform the following steps to install TIBCO Graph Database:

Procedure

1. Use one of the following archive files: Option Description

tib_tgdb_2.0.0_win_x86_64.tar.gz If your operating system is Windows

tib_tgdb_2.0.0_linux26gl212_x86_64.tar.gz If your operating system is Linux

tib_tgdb_2.0.0_macosx_x86_64.tar.gz If your operating system is Mac OS X

2. Unzip the archive file to a specific location. The files within the archive will be extracted to the desired location and TIBCO Graph Database is installed on your system.

What to do next

See the topic Graph Database Folder Structure to understand the folder structure of TIBCO Graph Database, and see the topic Configuring Graph Database to configure TIBCO Graph Database on your system.

TIBCO® Graph Database Getting Started Guide 7

Graph Database Folder Structure

TIBCO Graph Database folder (for example (tgdb/1.1) contains three folders and three files. The details about the files and folders are as follows:

Folders

The three folders and their details are as follows:

Folder Name Description

bin Contains server and admin executables and server configuration files.

data An empty directory, which is by default, configured as the database location.

lib Contains the Java Client API library.

examples Contains few exercises including the hands-on exercise mentioned in this guide. See the Hands- on Exercise topic for more details.

Files

The three files and their details are as follows:

File Name Description

license.txt The license agreement form in TXT format.

TIB_tgdb_2.0.0_readme.txt The Read Me file in TXT format.

TIB_tgdb_2.0.0_relnotes.pdf TIBCO Graph Database Release Notes in PDF format.

TIBCO® Graph Database Getting Started Guide 8

Configuring Graph Database

To configure TIBCO Graph Database, perform the following steps:

Procedure

1. Open the folder containing the TIBCO Graph Database files and folders (for example tgdb/1.1).

2. Within the tgdb/1.1 location, open the folder named bin. 3. Make the necessary modifications to the following files: a) initdb.conf - This file is used to configure the server for initializing the database. Refer to the file comments for specific settings. Also, see the initdb.conf topic for more details. b) tgdb.conf - This file is used to configure the server for running the database. Refer to the file comments for specific settings. Also, see the tgdb.conf topic for more details. File Information This topic provides details about the configuration files. The list of configuration files whose details will be provided are as follows:

● initdb.conf

● tgdb.conf

● tgsec.conf initdb.conf You can use the initdb.conf file to configure the server for initializing the database. The initdb.conf file defines:

● the database parameters

● the root user of the system (the user that will log in to the admin console)

● a default metadata for the database

● Metadata can also be created in the admin console. See the TIBCO Graph Database Administration Guide for more details.

● A default metadata can be defined in initdb.conf and new metadata objects can be added later using the admin console.

● Metadata can also be referred to as a schema.

This file also contains the database name, which needs to be at least three (3) characters long. For example: [initdb]name = db1. tgdb.conf You can use the tgdb.conf file to configure the server for running the database. The tgdb.conf file defines:

● database parameters (these must match the parameters in initdb.conf. See the topic initdb.conf for more details)

● transaction and query processor parameters

TIBCO® Graph Database Getting Started Guide 9

● log parameters

● network listeners (where clients connect to) - several listeners can be defined and each listener has a maximum defined connection

● IPv6 is supported.

● The URL format, when a client connection is established using IPv6, is as follows: tcp://[host:port]. Square brackets are required for IPv6. An example for IPv6 is as follows: tcp:// [fe80:0:0:0:e118:55ae:70a3:7369:8223]. In case of IPv4, square brackets are not required. An example for IPv4 is as follows: tcp://10.108.14.124:8222. tgsec.conf This conf file is referred by the initdb.conf and tgdb.conf configuration files.

See the topics initdb.conf and tgdb.conf for details on the configuration files.

The tgsec.conf file defines security configurations. You do not have to make any modifications in the tgsec.conf file.

TIBCO® Graph Database Getting Started Guide 10

Graph Database Server Commands and Controls

To run the Graph Database server you, must run the executable named tgdb. This executable is placed within the bin folder. A single server instance starts a single database.

The command to run tgdb is: tgdb [cmd] [options] -c|--config Commands can be any one of the following:

Command Format Description

-i, --initdb Initialize a Database. When running this, specify initdb.conf as the config file.

For example: tgdb -i -c

-s, --server Start a Database. When running this, specify tgdb.conf as the config file.

For example: tgdb -s -c

Options can be any one of the following:

Options Format Description

-f, --force Force creation. This deletes all the data in the directory specified by the conf file. The option can only be used with the -i option. It is valid only for the initdb command.

For example: tgdb -f -i -c

-Y, --accept-license Accepts End User License Agreement (EULA) without a prompt. Valid for all commands.

-h, --help Help

To run a new database instance, you must first initialize the database before running it. After configuring the conf files appropriately, run the following commands:

Command Description

tgdb -i -f -c Forcefully initializes a new database instance with the configurations in the conf file.

tgdb -s -c Starts the server with the targeted new database, specified in the tgdb conf file.

The first time you run initdb you will be prompted to accept the License Agreement.

TIBCO® Graph Database Getting Started Guide 11

Graph Database Admin Console

tgdb-admin is the executable to launch the Admin console. The format is as follows: tgdb-admin [--url [--uid [--pwd ]]] [option...] See the TIBCO Graph Database Administration Guide for details about the TIBCO Graph Database Admin Console.

TIBCO® Graph Database Getting Started Guide 12

Graph Database Client

The Graph Database client is an open source client. The community can contribute to the existing client or even create their own new client API. The clients are located in the following location: https://github.com/TIBCOSoftware/tgdb-client. The mentioned URL provides you access to the default implementation of a client API in Javadoc. Currently the GitHub has read-only privileges.

TIBCO® Graph Database Getting Started Guide 13

Hands-on Exercise

The following exercise gives a hands-on experience of using TIBCO Graph Database. The exercise uses the example of House of Bonaparte. The House of Bonaparte is an imperial and royal European founded in 1804 by I. The purpose of this exercise is to build the graph of that family.

You will find the artifacts, which were mentioned in this topic, in the following location: / examples/hierarchy. House of Bonaparte - Family Tree (Partial)

The hands-on exercise includes the following topics:

TIBCO® Graph Database Getting Started Guide 14

● Initializing the Database ● Starting the Database Server ● Defining the Metadata in the Admin Console ● Building the House of Bonaparte ● Searching for a Member of the House ● Updating a Member of the House

Initializing the Database There are two ways to define the metadata of the database:

Option 1: Define the metadata in the initdb.conf and run the tgdb init command.

Option 2: Create the metadata via the admin console (the server needs to be initialized and started first).

Prerequisites

See the Hands-on Exercise Overview to get an overview of the exercise.

Procedure

1. Type cd /bin and press the Enter key. 2. Make a copy of initdb.conf and name it inithousedb.conf. Edit the inithousedb.conf and within the section [initdb], set the name of database to housedb.

3. Perform this step only if you have selected Option 1. Skip this step if you have selected Option 2. Replace the sections [attrtypes], [nodetypes], [indices] and [users] with the following metadata: [attrtypes] memberName = @type:string crownName = @type:string houseHead = @type:boolean @default:false yearBorn = @type:int yearDied = @type:int reignStart = @type:date reignEnd = @type:date crownTitle = @type:string relType = @type:string

[nodetypes] houseMemberType = @attrs:memberName,crownName,yearBorn,yearDied,reignStart,reignEnd,crownTitle @pkey:memberName

[indices]

[users] napoleon = @passwd:bonaparte @role:user 4. Save the file inithousedb.conf. 5. Initialize the database using the command tgdb -i -c /bin/inithousedb.conf The output of the tgdb console should be: Database initialized successfully :TGSuccess. 6. Validate the database files, which were created successfully, placed in the /data/housedb location.

What to do next

See the topic Starting the Database Server for the next procedure.

TIBCO® Graph Database Getting Started Guide 15

Starting the Database Server To start the database server, perform the following steps:

Prerequisites

See the topic Initializing the Database for the previous procedure.

Procedure

1. Make a copy of tgdb.conf and name it housedb.conf.

2. Edit housedb.conf within the section [tgdb] and set the name of database to "housedb".

3. Start the server: tgdb -s -c /bin/housedb.conf 4. Check the tgdb output console for the following statements to validate successful start-up: “Initialized ProcessHeap Memory Manager” “Initialized Persistent Shared Memory Manager in directory: ../data/housedb” “Initialized and Loaded catalogue Info” “Successfully opened the database:../data/housedb” “Page manager started” “Transaction manager started” “Accepting clients on 0.0.0.0:8222”

What to do next

See the topic Defining the Metadata in the Admin Console for the next procedure.

Defining the Metadata in the Admin Console The following procedure should be performed only if you have chosen Option 2 when you initialized the database. See the topic Initializing the Database for more details.

Prerequisites

See the topic Starting the Database Server for the previous procedure.

Procedure

1. Create an admin script file with the following content and save it as houseAdminScript.txt: # Schema creation for the House of Bonaparte

# create a new user to connect to db create user napoleon passwd=bonaparte

# create attribute descriptions create attrdesc memberName as string create attrdesc houseHead as boolean create attrdesc crownName as string create attrdesc crownTitle as string create attrdesc yearBorn as int create attrdesc yearDied as int create attrdesc reignStart as date create attrdesc reignEnd as date create attrdesc relType as string

# create node type create nodetype houseMemberType attributes(memberName, houseHead, crownName, crownTitle, yearBorn, yearDied, reignStart, reignEnd) pkeys (memberName)

disconnect exit

TIBCO® Graph Database Getting Started Guide 16

2. Run the admin script in TGDB admin: tgdb-admin --url tcp://localhost:8222 --uid admin --pwd admin --file /bin/ houseAdminScript.txt The admin console output is as shown in the following example. The metadata is also created. /bin>tgdb-admin --url tcp://localhost:8222 --uid admin --pwd admin --file [...] Successfully connected to server tcp://localhost:8222 with user admin. # Schema creation for the House of Bonaparte # create a new user to connect to db create user napoleon passwd=bonaparte Successfully created user on server.

# create attribute descriptions create attrdesc memberName as string Successfully created attrdesc on server. create attrdesc houseHead as boolean Successfully created attrdesc on server. create attrdesc crownName as string Successfully created attrdesc on server. create attrdesc crownTitle as string Successfully created attrdesc on server. create attrdesc yearBorn as int Successfully created attrdesc on server. create attrdesc yearDied as int Successfully created attrdesc on server. create attrdesc reignStart as date Successfully created attrdesc on server. create attrdesc reignEnd as date Successfully created attrdesc on server. create attrdesc relType as string Successfully created attrdesc on server.

# create node type create nodetype houseMemberType attributes(memberName, houseHead, crownName, crownTitle, yearBorn, yearDied, reignStart, reignEnd) pkeys (memberName) Successfully created nodetype on server.

Disconnect Successfully disconnected from server.

exit

What to do next

See the topic Building the House of Bonaparte for the next procedure.

Building the House of Bonaparte You can insert data in the graph database (and later search and update the graph) using the Java client API.

Prerequisites

See the topic Defining the Metadata in the Admin Console for the previous procedure. The Javadoc is located at https://github.com/TIBCOSoftware/tgdb-client/tree/master/client/java/javadoc.

import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Hashtable;

import com.tibco.tgdb.connection.TGConnection; import com.tibco.tgdb.connection.TGConnectionFactory; import com.tibco.tgdb.model.TGEdge; import com.tibco.tgdb.model.TGEdgeType;

TIBCO® Graph Database Getting Started Guide 17

import com.tibco.tgdb.model.TGGraphMetadata; import com.tibco.tgdb.model.TGGraphObjectFactory; import com.tibco.tgdb.model.TGNode; import com.tibco.tgdb.model.TGNodeType;

/** * Build the House of Bonaparte graph. * The House of Bonaparte is an imperial and royal European dynasty founded in 1804 by Napoleon I. * * Each member has the following characteristics : * -memberName : Name of member (primary key) * -crownName : Name while reigning * -crownTitle : Title while reigning * -houseHead : There is always a head of the house at a given time. * -yearBorn : Year of birth * -yearDied : Year of death * -reignStart : Date reign started * -reignEnd : Date reign ended * * Usage : java BuildGraph * */ public class BuildGraph {

// Members of the House to be inserted in the database final static Object houseMemberData[][] = { // memberName, crownName, houseHead, yearBorn, yearDied, reignStart, reignEnd, crownTitle { "Carlo Bonaparte", null, false, 1746, 1785, null, null, null }, { "Letizia Ramolino", null, false, 1750, 1836, null, null, null }, { "", "Joseph I", false, 1768, 1844, "6 Jun 1808", "11 Dec 1813", "King of " }, { "Napoleon Bonaparte", "Napoleon I", false, 1769, 1821, "18 May 1804", "22 Jun 1815", "" }, { "", null, false, 1775, 1840, null, null, null }, { "Elisa Bonaparte", "Elisa Bonaparte", false, 1777, 1820, "3 Mar 1809", "1 Feb 1814", "Grand Duchess of " }, { "", "Louis I", false, 1778, 1846, "5 Jun 1806", "1 Jul 1810", "King of " }, { "", null, false, 1780, 1825, null, null, null }, { "Caroline Bonaparte", null, false, 1782, 1839, null, null, null }, { "Jerome Bonaparte", "Jerome I", false, 1784, 1860, "8 Jul 1807", "26 Oct 1813", "King of Westphalia" }, { "Marie Louise of Austria", null, false, 1791, 1847, null, null, "Empress Consort of the French" }, { "Josephine of Beauharnais", null, false, 1763, 1814, null, null, "Empress Consort of the French" }, { "Alexandre of Beauharnais", null, false, 1760, 1794, null, null, null }, { "Betsy Patterson", null, false, 1785, 1879, null, null, null }, { "Catharina of Wurttemberg", null, false, 1783, 1835, null, null, " of Westphalia" }, { "Francois Bonaparte", "Napoleon II", false, 1811, 1832, "22 Jun 1815", "7 Jul 1815", "Emperor of the French" }, { "Hortense of Beauharnais", null, false, 1783, 1837, null, null, "Queen Consort of Holland" }, { "Jerome Napoleon", null, false, 1805, 1870, null, null, null }, { "Prince Napoleon", null, false, 1822, 1891, null, null, null }, { "Louis Napoleon", "Napoleon III", true, 1808, 1873, "2 Dec 1852", "4 Sep 1870", "Emperors of the French" }, { "Napoleon-Louis Bonaparte", "Louis II", false, 1804, 1831, "1 Jul 1810", "13 Jul 1810", "King of Holland" }, { "Napoleon IV Eugene", null, true, 1856, 1879, null, null, null }, { "Napoleon V Victor", null, true, 1862, 1926, null, null, null }, { "Marie Clotilde Bonaparte", null, false, 1912, 1996, null, null, null }, { "Napoleon VI Louis", null, true, 1914, 1997, null, null, null }, { "Napoleon VII Charles", null, true, 1950, null, null, null, null }, { "Napoleon VIII Jean-Christophe", null, true, 1986, null, null, null, null }, { "Sophie Catherine Bonaparte", null, false, 1992, null, null, null, null } };

TIBCO® Graph Database Getting Started Guide 18

// Relation among the members of the House to be inserted in the database final static Object houseRelationData[][] = { // From memberName, To memberName, relation type { "Carlo Bonaparte", "Letizia Ramolino", "spouse" }, { "Carlo Bonaparte", "Joseph Bonaparte", "child" }, { "Letizia Ramolino", "Joseph Bonaparte", "child" }, { "Carlo Bonaparte", "Napoleon Bonaparte", "child" }, { "Letizia Ramolino", "Napoleon Bonaparte", "child" }, { "Carlo Bonaparte", "Lucien Bonaparte", "child" }, { "Letizia Ramolino", "Lucien Bonaparte", "child" }, { "Carlo Bonaparte", "Elisa Bonaparte", "child" }, { "Letizia Ramolino", "Elisa Bonaparte", "child" }, { "Carlo Bonaparte", "Louis Bonaparte", "child" }, { "Letizia Ramolino", "Louis Bonaparte", "child" }, { "Carlo Bonaparte", "Pauline Bonaparte", "child" }, { "Letizia Ramolino", "Pauline Bonaparte", "child" }, { "Carlo Bonaparte", "Caroline Bonaparte", "child" }, { "Letizia Ramolino", "Caroline Bonaparte", "child" }, { "Carlo Bonaparte", "Jerome Bonaparte", "child" }, { "Letizia Ramolino", "Jerome Bonaparte", "child" },

{ "Napoleon Bonaparte", "Marie Louise of Austria", "spouse" }, { "Napoleon Bonaparte", "Francois Bonaparte", "child" }, { "Marie Louise of Austria", "Francois Bonaparte", "child" },

{ "Napoleon Bonaparte", "Josephine of Beauharnais", "spouse" },

{ "Alexandre of Beauharnais", "Josephine of Beauharnais", "spouse" }, { "Alexandre of Beauharnais", "Hortense of Beauharnais", "child" }, { "Josephine of Beauharnais", "Hortense of Beauharnais", "child" },

{ "Louis Bonaparte", "Hortense of Beauharnais", "spouse" }, { "Louis Bonaparte", "Louis Napoleon", "child" }, { "Hortense of Beauharnais", "Louis Napoleon", "child" }, { "Louis Bonaparte", "Napoleon-Louis Bonaparte", "child" }, { "Hortense of Beauharnais", "Napoleon-Louis Bonaparte", "child" },

{ "Jerome Bonaparte", "Betsy Patterson", "spouse" }, { "Jerome Bonaparte", "Jerome Napoleon", "child" }, { "Betsy Patterson", "Jerome Napoleon", "child" },

{ "Jerome Bonaparte", "Catharina of Wurttemberg", "spouse" }, { "Jerome Bonaparte", "Prince Napoleon", "child" }, { "Catharina of Wurttemberg", "Prince Napoleon", "child" },

{ "Louis Napoleon", "Napoleon IV Eugene", "child" },

{ "Prince Napoleon", "Napoleon V Victor", "child" },

{ "Napoleon V Victor", "Napoleon VI Louis", "child" },

{ "Napoleon VI Louis", "Napoleon VII Charles", "child" },

{ "Napoleon VII Charles", "Napoleon VIII Jean-Christophe", "child" }, { "Napoleon VII Charles", "Sophie Catherine Bonaparte", "child" } };

public static void main(String[] args) throws Exception { String url = "tcp://127.0.0.1:8222"; String user = "napoleon"; String pwd = "bonaparte"; TGConnection conn = null; try { conn = TGConnectionFactory.getInstance().createConnection(url, user, pwd, null); conn.connect();

TGGraphObjectFactory gof = conn.getGraphObjectFactory(); if (gof == null) { throw new Exception("Graph object not found"); }

TIBCO® Graph Database Getting Started Guide 19

TGGraphMetadata gmd = conn.getGraphMetadata(true); TGNodeType houseMemberType = gmd.getNodeType("houseMemberType"); if (houseMemberType == null) throw new Exception("Node type not found"); TGNode houseMember; Hashtable houseMemberTable = new Hashtable();

// // Insert node data into database // for (int i = 0; i < houseMemberData.length; i++) { houseMember = gof.createNode(houseMemberType); houseMember.setAttribute("memberName", houseMemberData[i][0]); houseMember.setAttribute("crownName", houseMemberData[i][1]); houseMember.setAttribute("houseHead", houseMemberData[i][2]); houseMember.setAttribute("yearBorn", houseMemberData[i][3]); houseMember.setAttribute("yearDied", houseMemberData[i][4]); houseMember.setAttribute("crownTitle", houseMemberData[i][7]);

Calendar reignStart = Calendar.getInstance(); if (houseMemberData[i][5] != null) { reignStart.setTime((new SimpleDateFormat("dd MMM yyyy").parse((String) houseMemberData[i][5]))); houseMember.setAttribute("reignStart", reignStart); } else houseMember.setAttribute("reignStart", null);

Calendar reignEnd = Calendar.getInstance(); if (houseMemberData[i][6] != null) { reignEnd.setTime((new SimpleDateFormat("dd MMM yyyy").parse((String) houseMemberData[i][6]))); houseMember.setAttribute("reignEnd", reignEnd); } else houseMember.setAttribute("reignEnd", null);

conn.insertEntity(houseMember); conn.commit(); // Write data to database System.out.println("Transaction completed for Node : " + houseMember.getAttribute("memberName").getAsString()); houseMemberTable.put(houseMember.getAttribute("memberName").getAsString(), houseMember); }

System.out.println("------");

// // Insert edge data into database // TGNode houseMemberFrom; TGNode houseMemberTo; TGEdge houseRelation; TGEdge.DirectionType houseRelationDirection; for (int i = 0; i < houseRelationData.length; i++) { houseMemberFrom = houseMemberTable.get(houseRelationData[i][0]); houseMemberTo = houseMemberTable.get(houseRelationData[i][1]); houseRelationDirection = houseRelationData[i][2].equals("spouse") ? TGEdge.DirectionType.UnDirected : TGEdge.DirectionType.Directed; houseRelation = gof.createEdge(houseMemberFrom, houseMemberTo, houseRelationDirection); houseRelation.setAttribute("relType", houseRelationData[i][2]); conn.insertEntity(houseRelation); conn.commit(); System.out.println("Transaction completed for Edge : " + houseMemberFrom.getAttribute("memberName").getAsString() + " to " + houseMemberTo.getAttribute("memberName").getAsString()); } System.out.println("\nHouse of Bonaparte graph completed successfully");

TIBCO® Graph Database Getting Started Guide 20

} finally { if (conn != null) conn.disconnect(); } } }

Procedure

1. Save the Java code shown earlier in a file named BuildGraph.java. 2. Compile the file using the command javac -cp /lib/tgdb-client.jar BuildGraph.java. 3. Run the compiled file using the command java -cp /lib/tgdb-client.jar:. BuildGraph. You will see the following transactions for nodes and edges executed successfully: Transaction completed for Node : Carlo Bonaparte Transaction completed for Node : Letizia Ramolino Transaction completed for Node : Joseph Bonaparte Transaction completed for Node : Napoleon Bonaparte [...] ------Transaction completed for Edge : Carlo Bonaparte to Letizia Ramolino Transaction completed for Edge : Carlo Bonaparte to Joseph Bonaparte [...] House of Bonaparte graph completed successfully 4. The data is saved on the disk. You can stop (use the command "stop server" in the Admin console) and restart the server. If you run the BuildGraph program again, an exception UniqueConstraintViolation will be displayed. The exception is displayed because a primary key constraint has been added to the member name (@pkey memberName) when the metadata was defined.

● See how the node (member) has been created and the attributes, which were defined earlier, have been set using node.setAttribute(). ● See how the data has been inserted using insertEntity() call and committed to the database using commit() call. It is called transacted insert. ● See how the edges (relation) has been created, between two nodes, using the createEdge() call. The edges have direction and can be bi-directional, directed, or undirected.

What to do next

See the topic Searching for a Member of the House for the next procedure.

Searching for a Member of the House Once the graph is complete you can search for the given node and get its characteristics. In the exercise you will search for a member of the House and get his or her characteristics.

Prerequisites

See the topic Building the House of Bonaparte for the previous procedure.

import java.text.SimpleDateFormat; import java.util.Calendar;

import com.tibco.tgdb.connection.TGConnection; import com.tibco.tgdb.connection.TGConnectionFactory; import com.tibco.tgdb.model.TGAttribute;

TIBCO® Graph Database Getting Started Guide 21

import com.tibco.tgdb.model.TGEdge; import com.tibco.tgdb.model.TGEntity; import com.tibco.tgdb.model.TGGraphObjectFactory; import com.tibco.tgdb.model.TGKey; import com.tibco.tgdb.model.TGNode;

/** * Search for a member in the House of Bonaparte graph * and display the member attributes and children * * Usage : java SearchGraph -memberName "Carlo Bonaparte" * */ public class SearchGraph {

static String url = "tcp://127.0.0.1:8222"; static String user = "napoleon"; static String pwd = "bonaparte";

static String memberName = "Napoleon Bonaparte";

public static void main(String[] args) throws Exception {

for (int i=0; i

TGConnection conn = null; try { conn = TGConnectionFactory.getInstance().createConnection(url, user, pwd, null); conn.connect();

TGGraphObjectFactory gof = conn.getGraphObjectFactory(); if (gof == null) { throw new Exception("Graph object not found"); }

conn.getGraphMetadata(true);

TGKey houseKey = gof.createCompositeKey("houseMemberType");

houseKey.setAttribute("memberName", memberName); System.out.printf("Searching for member '%s'...\n",memberName); TGEntity houseMember = conn.getEntity(houseKey, null); if (houseMember != null) { SimpleDateFormat simpleFormat = new SimpleDateFormat("dd MMM yyyy"); System.out.printf("House member '%s' found \n",houseMember.getAttribute("memberName").getAsString()); for (TGAttribute attr : houseMember.getAttributes()) { if (attr.getValue() == null) System.out.printf("\t%s: %s\n", attr.getAttributeType().getName(), ""); else System.out.printf("\t%s: %s\n", attr.getAttributeType().getName(), (attr.getValue() instanceof Calendar)? (simpleFormat.format(((Calendar)attr.getValue()).getTime())):attr.getValue()); } for (TGEdge relation : ((TGNode)houseMember).getEdges()) { if (relation.getVertices()[0].getAttribute("memberName") == houseMember.getAttribute("memberName") && relation.getAttribute("relType").getAsString().equals("child")) System.out.printf("\tchild: %s\n", relation.getVertices() [1].getAttribute("memberName").getAsString()); } } else { System.out.printf("House member '%s' not found", memberName); } } finally { if (conn != null)

TIBCO® Graph Database Getting Started Guide 22

conn.disconnect(); } } }

Procedure

1. Save the earlier provided Java code in a file named SearchGraph.java. 2. Compile the code using the command javac -cp /lib/tgdb-client.jar SearchGraph.java

3. Run the compiled file using the command java -cp /lib/tgdb-client.jar:. SearchGraph -memberName "Napoleon Bonaparte" The output of the program provides details of the member: Searching for member 'Napoleon Bonaparte'... House member 'Napoleon Bonaparte' found reignStart: 22 Jun 1815 houseHead: false yearDied: 1821 crownName: Napoleon I crownTitle: Emperor of the French memberName: Napoleon Bonaparte yearBorn: 1769 reignEnd: 22 Jun 1815 child: Francois Bonaparte Additionally, you can also search for other members of the House by passing another name using the parameter: SearchGraph -memberName "Carlo Bonaparte".

● See how a TGKey was first defined and a node was received using the getEntity() call. ● See how by using the node (member) searched, the edges (relation) were retrieved using the getEdges() call to get to the children of the searched node (member).

What to do next

See the topic Updating a Member of the House for the next procedure

Updating a Member of the House To update the characteristics of a given node or member, perform the following steps:

Prerequisites

See the topic Searching for a Member of the House for the previous procedure.

import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar;

import com.tibco.tgdb.connection.TGConnection; import com.tibco.tgdb.connection.TGConnectionFactory; import com.tibco.tgdb.model.TGEntity; import com.tibco.tgdb.model.TGGraphObjectFactory; import com.tibco.tgdb.model.TGKey;

/** * For a given member of the House, update the attributes * * Usage : java UpdateGraph [options] * * where options are: * -memberName Required. Member name - "Napoleon Bonaparte"

TIBCO® Graph Database Getting Started Guide 23

* -crownName Optional. Name while reigning - "Napoleon XVIII" * -crownTitle Optional. Title while reigning - "King of USA" * -houseHead Optional. Head of the house - true or false * -yearBorn Optional. Year of birth - 2004 * -yearDied Optional. Year of death - 2016 or null if still alive * -reignStart Optional. Date reign starts (format dd MMM yyyy) - 20 Jan 2008 or null if never reigned * -reignEnd Optional. Date reign ends (format dd MMM yyyy) - 08 Nov 2016 or null if never reigned or still reigning * * For instance to update the house member named "Napoleon Bonaparte" : * java UpdateGraph -memberName "Napoleon Bonaparte" -crownName "Napoleon XVIII" - crownTitle "King of USA" -yearDied null -reignEnd "31 Jan 2016" * */ public class UpdateGraph {

static String url = "tcp://127.0.0.1:8222"; static String user = "napoleon"; static String pwd = "bonaparte";

static String memberName = null; static String crownName = null; static String crownTitle = null; static String yearBorn = null; static String yearDied = null; static String reignStart = null; static String reignEnd= null; static String houseHead = null;

static void parseArgs(String[] args) throws Exception { for (int i=0; i

public static void main(String[] args) throws Exception {

parseArgs(args);

if (memberName == null) { System.out.println("No house member to update.\nArguments example: - memberName \"Napoleon Bonaparte\" -crownName \"Grand Napoleon\" -crownTitle \"King of the world\" -reignStart \"8 Nov 2001\" -yearDied 2016"); return; }

TGConnection conn = null; try { conn = TGConnectionFactory.getInstance().createConnection(url, user, pwd, null); conn.connect();

TGGraphObjectFactory gof = conn.getGraphObjectFactory(); if (gof == null) { throw new Exception("Graph object not found"); }

TIBCO® Graph Database Getting Started Guide 24

conn.getGraphMetadata(true);

TGKey houseKey = gof.createCompositeKey("houseMemberType");

houseKey.setAttribute("memberName", memberName); System.out.printf("Searching for member '%s'...\n",memberName); TGEntity houseMember = conn.getEntity(houseKey, null); if (houseMember != null) { System.out.printf("House member '%s' found \n",houseMember.getAttribute("memberName").getAsString()); if (crownName != null) houseMember.setAttribute("crownName", crownName); if (crownTitle != null) houseMember.setAttribute("crownTitle", crownTitle); if (houseHead != null) houseMember.setAttribute("houseHead", Boolean.parseBoolean(houseHead)); if (yearBorn != null) houseMember.setAttribute("yearBorn", Integer.parseInt(yearBorn)); if (yearDied != null) { if (yearDied.equals("null")) houseMember.setAttribute("yearDied", null); else houseMember.setAttribute("yearDied", Integer.parseInt(yearDied)); } Calendar date = Calendar.getInstance(); if (reignStart != null) { if (reignStart.equals("null")) houseMember.setAttribute("reignStart", null); else { try { date.setTime((new SimpleDateFormat("dd MMM yyyy").parse(reignStart))); houseMember.setAttribute("reignStart", date); } catch (ParseException e) { throw new Exception("Member update failed - Wrong parameter: -reignStart format should be \"dd MMM yyyy\""); } } } if (reignEnd != null) { if (reignEnd.equals("null")) houseMember.setAttribute("reignEnd", null); else { try { date.setTime((new SimpleDateFormat("dd MMM yyyy").parse(reignEnd))); houseMember.setAttribute("reignEnd", date); } catch (ParseException e) { throw new Exception("Member update failed - Wrong parameter: -reignEnd format should be \"dd MMM yyyy\""); } } }

conn.updateEntity(houseMember); conn.commit(); System.out.printf("House member '%s' updated successfully\n", memberName); } else { System.out.printf("House member '%s' not found\n", memberName); } } finally { if (conn != null) conn.disconnect(); }

TIBCO® Graph Database Getting Started Guide 25

} }

Procedure

1. Save the earlier provided java code in a file named UpdateGraph.java.

2. Compile the code file using the command javac -cp /lib/tgdb-client.jar UpdateGraph.java.

3. Run the compiled file using the command java -cp /lib/tgdb-client.jar:. UpdateGraph -memberName "Napoleon Bonaparte" -houseHead true -yearBorn 1946 -yearDied null -crownTitle "King of USA" -crownName "Napoleon X" -reignStart "20 Jan 2017" - reignEnd "19 Jan 2021" The output upon successful update is as follows: Searching for member 'Napoleon Bonaparte'... House member 'Napoleon Bonaparte' found House member 'Napoleon Bonaparte' updated successfully

4. You can run the SearchGraph program again to validate the changes. See the topic Searching for a Member of the House for more details. The search results is as follows: House member 'Napoleon Bonaparte' found reignStart: 20 Jan 2017 houseHead: true yearDied: crownName: Napoleon X crownTitle: King of USA memberName: Napoleon Bonaparte yearBorn: 1946 reignEnd: 19 Jan 2021

● See how the attributes have been updated with the node.setAttribute() call, and see how the node has been updated using the updateEntity() call followed by the commit() call. This is called a transacted update.

TIBCO® Graph Database Getting Started Guide 26

Legal and Third-Party Notices

SOME TIBCO SOFTWARE EMBEDS OR BUNDLES OTHER TIBCO SOFTWARE. USE OF SUCH EMBEDDED OR BUNDLED TIBCO SOFTWARE IS SOLELY TO ENABLE THE FUNCTIONALITY (OR PROVIDE LIMITED ADD-ON FUNCTIONALITY) OF THE LICENSED TIBCO SOFTWARE. THE EMBEDDED OR BUNDLED SOFTWARE IS NOT LICENSED TO BE USED OR ACCESSED BY ANY OTHER TIBCO SOFTWARE OR FOR ANY OTHER PURPOSE. USE OF TIBCO SOFTWARE AND THIS DOCUMENT IS SUBJECT TO THE TERMS AND CONDITIONS OF A LICENSE AGREEMENT FOUND IN EITHER A SEPARATELY EXECUTED SOFTWARE LICENSE AGREEMENT, OR, IF THERE IS NO SUCH SEPARATE AGREEMENT, THE CLICKWRAP END USER LICENSE AGREEMENT WHICH IS DISPLAYED DURING DOWNLOAD OR INSTALLATION OF THE SOFTWARE (AND WHICH IS DUPLICATED IN THE LICENSE FILE) OR IF THERE IS NO SUCH SOFTWARE LICENSE AGREEMENT OR CLICKWRAP END USER LICENSE AGREEMENT, THE LICENSE(S) LOCATED IN THE “LICENSE” FILE(S) OF THE SOFTWARE. USE OF THIS DOCUMENT IS SUBJECT TO THOSE TERMS AND CONDITIONS, AND YOUR USE HEREOF SHALL CONSTITUTE ACCEPTANCE OF AND AN AGREEMENT TO BE BOUND BY THE SAME. ANY SOFTWARE ITEM IDENTIFIED AS THIRD PARTY LIBRARY IS AVAILABLE UNDER SEPARATE SOFTWARE LICENSE TERMS AND IS NOT PART OF A TIBCO PRODUCT. AS SUCH, THESE SOFTWARE ITEMS ARE NOT COVERED BY THE TERMS OF YOUR AGREEMENT WITH TIBCO, INCLUDING ANY TERMS CONCERNING SUPPORT, MAINTENANCE, WARRANTIES, AND INDEMNITIES. DOWNLOAD AND USE OF THESE ITEMS IS SOLELY AT YOUR OWN DISCRETION AND SUBJECT TO THE LICENSE TERMS APPLICABLE TO THEM. BY PROCEEDING TO DOWNLOAD, INSTALL OR USE ANY OF THESE ITEMS, YOU ACKNOWLEDGE THE FOREGOING DISTINCTIONS BETWEEN THESE ITEMS AND TIBCO PRODUCTS. This document is subject to U.S. and international copyright laws and treaties. No part of this document may be reproduced in any form without the written authorization of TIBCO Software Inc. TIBCO, the TIBCO logo, the TIBCO O logo, and Graph Database are either registered trademarks or trademarks of TIBCO Software Inc. in the United States and/or other countries. All other product and company names and marks mentioned in this document are the property of their respective owners and are mentioned for identification purposes only. This software may be available on multiple operating systems. However, not all operating system platforms for a specific software version are released at the same time. Please see the readme.txt file for the availability of this software version on a specific operating system platform. THIS DOCUMENT IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION HEREIN; THESE CHANGES WILL BE INCORPORATED IN NEW EDITIONS OF THIS DOCUMENT. TIBCO SOFTWARE INC. MAY MAKE IMPROVEMENTS AND/OR CHANGES IN THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THIS DOCUMENT AT ANY TIME. THE CONTENTS OF THIS DOCUMENT MAY BE MODIFIED AND/OR QUALIFIED, DIRECTLY OR INDIRECTLY, BY OTHER DOCUMENTATION WHICH ACCOMPANIES THIS SOFTWARE, INCLUDING BUT NOT LIMITED TO ANY RELEASE NOTES AND "READ ME" FILES. This and other products of TIBCO Software Inc. may be covered by registered patents. Please refer to TIBCO's Virtual Patent Marking document (https://www.tibco.com/patents) for details. Copyright © 2020. TIBCO Software Inc. All Rights Reserved.

TIBCO® Graph Database Getting Started Guide