Sample Code

 

// 
// Copyright (C) 2018, Boiler Bay Inc. All rights reserved.
// 
// This is licensed under the MIT license.
//

package com.infinitydb.examples;

import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import com.infinitydb.Attribute;
import com.infinitydb.EntityClass;
import com.infinitydb.InfinityDB;
import com.infinitydb.ItemSpace;
import com.infinitydb.map.db.InfinityDBMap;
import com.infinitydb.remote.Authority;
import com.infinitydb.remote.Connector;
import com.infinitydb.remote.ItemSpaceAccessPermissions;
import com.infinitydb.remote.KeyStoreAccessor;
import com.infinitydb.remote.RemoteClientItemSpace;
import com.infinitydb.remote.SSLCertificateNameVerifier;
import com.infinitydb.remote.SocketConnector;

public class OnlineExamples {

    // Some EntityClasses and Attributes that provide 'internal metadata'
    // in each Item for very flexible, extensible structures.
    // These are well compressed in storage.

    // These are named [A-Z][A-Za-z0-9._-]*
    static final EntityClass TREES = new EntityClass("Trees");
    // These are named [a-z][A-Za-z0-9._-]*
    static final Attribute LEAF_TYPE = new Attribute("leafType");
    // For a nested table
    static final Attribute NURSERY = new Attribute("nursery");
    static final EntityClass NURSERY_LOCATION =
            new EntityClass("NurseryLocation");
    static final Attribute QUANTITY_ON_HAND = new Attribute("quantityOnHand");

    static final long MAX_CACHE_SIZE = 100_000;

    public static void main(String... args)
            throws IOException {

        try (InfinityDB db = InfinityDB.createTemporary(MAX_CACHE_SIZE)) {

            // The db 'ItemSpace' model goes about 1MOps/s, with 8 cores
            db.insert(TREES, "oak", LEAF_TYPE, "deciduous");
            db.insert(TREES, "red fir", LEAF_TYPE, "conifer");

            // When we add larch, we find 'deciduous' and 'conifer' are not
            // exclusive! Now we use a multi-value attribute.
            db.insert(TREES, "larch", LEAF_TYPE, "deciduous");
            db.insert(TREES, "larch", LEAF_TYPE, "conifer");

            // Use the optional Map interface, an extended
            // ConcurrentNavigableMap
            InfinityDBMap<EntityClass, String> map = new InfinityDBMap<>(db);
            for (String treeName : map.getSet(TREES)) {
                System.out.println("treeName: " + treeName);
            }

            // Add a new tree with a composite key "oak" "red".
            // The key is compound for only one of the Items!
            // That is a unique kind of flexibility.
            map.add(TREES, "oak", "red", LEAF_TYPE, "deciduous");

            // Now with the composite key, we need to iterate by tuples
            for (Object[] treeName : map.getTupleSet(TREES)) {
                System.out.println("tree: " + Arrays.toString(treeName));
            }

            // Iterate the larch's leaf types. getStringSet selects only the
            // Strings
            for (String leafType : map.getStringSet(TREES, "larch",
                    LEAF_TYPE)) {
                System.out.println("larch leaf type: " + leafType);
            }

            /*
             * Add some new Nurseries Under a 'nursery' Attribute, with a
             * 'Location' EntityClass under that. InfinityDBMaps have an
             * additional add() method, like a Set. Now we have a nested table.
             * That is a unique kind of flexibility.
             */
            map.add(TREES, "oak", NURSERY, NURSERY_LOCATION, "US",
                    "California", "Aptos", QUANTITY_ON_HAND, 3);
            map.add(TREES, "oak", "red", NURSERY, NURSERY_LOCATION, "US",
                    "California", "Capitola", QUANTITY_ON_HAND, 5);

            /*
             * How many total oaks of any sub-type do we have in all nursery
             * locations?
             */

            // This is hard without the variable compound keys.
            String tree = "oak";
            int treeTotalQuantity = 0;

            // The map containing only the trees having a particular first
            // component
            // in the name.
            InfinityDBMap<Object[], Object[]> treeSubMap =
                    map.getStringMap(TREES).getTupleMap(tree);

            // Iterate the variable compound key of tree name under just the
            // first component.
            // This will iterate every tree under "oak", getting "oak" itself,
            // plus "oak" "red". We allow locations to be variable-compound too.
            // This is very fast - the loops are small, and we don't iterate
            // everything.
            for (Object[] treeSubName : treeSubMap.keyTupleSet()) {
                InfinityDBMap<Object[], Object> locations =
                        treeSubMap.getAttributeMap(treeSubName)
                                .getEntityClassMap(NURSERY)
                                .getTupleMap(NURSERY_LOCATION);
                // Iterate locations in the nested locations map
                for (Object[] location : locations.keyTupleSet()) {
                    // The 0 is default
                    Long quantity = locations.getAttributeMap(location)
                            .getLong(QUANTITY_ON_HAND, 0);
                    treeTotalQuantity += quantity;
                }
            }
            System.out.println("oak total quantity = " + treeTotalQuantity);

            // The 'global' tx. There is also 'optimistic' for fine-grain.
            // This is not really useful, as the temp file gets deleted.
            db.commit();

            /*
             * Remote access to an InfinityDB on the infinitydb.com server.
             */

            // Optionally match also based on common name being "infinitydb"
            // It handles CN, IP, DNS, and blacklists.
//             SSLCertificateNameVerifier sslCertificateNameVerifier =
//             new SSLCertificateNameVerifier(new String[] {"infinitydb"} ,
//             null, null, null, null, null);
            SSLCertificateNameVerifier sslCertificateNameVerifier = null;
            String databaseName = "demo/writeable";
            // default cacerts password.
            String cacertsPassWord = "changeit";
            // No private key or password, default cacerts in
            // $JAVA_HOME/lib/security/cacerts. This handles both private key
            // and cacerts.
            KeyStoreAccessor keystoreAccessor =
                    new KeyStoreAccessor(null, null, null, cacertsPassWord,
                            sslCertificateNameVerifier);
            Authority authority = new Authority("testUser", "db");
            // RemoteItemSpaceServer is at the http server port + 1
            URL url = new URL("https", "infinitydb.com", 37412,
                    "/" + databaseName);
            // For any future server params
            Map<String, String> formParams = new HashMap<>();
            SocketConnector connector = new SocketConnector(url, authority,
                    keystoreAccessor, formParams,
                    ItemSpaceAccessPermissions.READ_WRITE);

            ItemSpace remoteClientItemSpace = new RemoteClientItemSpace(connector);
            
            // Put Items in the demo/writeable remote
            remoteClientItemSpace.insert(TREES, "oak", LEAF_TYPE, "deciduous");
            remoteClientItemSpace.insert(TREES, "red fir", LEAF_TYPE,
                    "conifer");
            // Iterate the trees remotely.
            InfinityDBMap<EntityClass, String> remoteMap =
                    new InfinityDBMap<>(remoteClientItemSpace);
            for (String treeName : remoteMap.getSet(TREES)) {
                System.out.println("treeName: " + treeName);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}