/*
* The MIT License (MIT)
*
* Copyright (c) 2013-2017 Cinchapi Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.cinchapi.concourse.example.bank;
import com.cinchapi.concourse.Concourse;
import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
/**
* An implementation of the {@link Customer} interface that uses Concourse for
* data storage.
*
* @author Jeff Nelson
*/
public class ConcourseCustomer implements Customer {
// NOTE: For the purpose of this example, we don't store any data about the
// Customer locally so that we can illustrate how you would query Concourse
// to get the data. In a real application, you always want to cache
// repeatedly used data locally.
/**
* Since Concourse does not have tables, we store a special key in each
* record to indicate the class to which the record/object belongs. This
* isn't necessary, but it helps to ensure logical consistency between the
* application and the database.
*/
private final static String CLASS_KEY_NAME = "_class";
/**
* The id of the Concourse record that holds the data for an instance of
* this class.
*/
private final long id;
/**
* This constructor creates a new record in Concourse and inserts the data
* expressed in the parameters.
*
* @param firstName the customer's first name
* @param lastName the customer's last name
*/
public ConcourseCustomer(String firstName, String lastName) {
Concourse concourse = Constants.CONCOURSE_CONNECTIONS.request();
try {
Multimap<String, Object> data = HashMultimap.create();
data.put(CLASS_KEY_NAME, getClass().getName());
data.put("first_name", firstName);
data.put("last_name", lastName);
this.id = concourse.insert(data);
}
finally {
Constants.CONCOURSE_CONNECTIONS.release(concourse);
}
}
/**
* This constructor loads an existing object from Concourse.
*
* @param id the id of the record that holds the data for the object we want
* to load
*/
public ConcourseCustomer(long id) {
Concourse concourse = Constants.CONCOURSE_CONNECTIONS.request();
try {
Preconditions.checkArgument(getClass().getName().equals(
concourse.get(CLASS_KEY_NAME, id)));
this.id = id;
// NOTE: If this were a real application, it would be a god idea to
// preload frequently used attributes here and cache them locally
// (or maybe even in an external cache like Memcache or Redis).
}
finally {
Constants.CONCOURSE_CONNECTIONS.release(concourse);
}
}
@Override
public long getId() {
return id;
}
@Override
public String toString(){
return getClass().getName() + " "+ id;
}
}