Any idea on how to define indexes on data stored with Akiban's Persistit key/value store?
There isn't first class/API support for secondary indexes in Persistit. That isn't to say you can't create indexes though!
What is an index? In practice, all an index contains is another copy of the data. For example, in a relational database with a users table, an index on the first_name column would allow efficient look-up by first name. That can be achieved by storing an additional copy of the first name with the primary identifier to create a "link" back to the main row.
Here's an isolated example of that:
import com.persistit.*;
import com.persistit.exception.*;
import java.io.*;
import java.util.*;
public class IndexDemo implements AutoCloseable
{
public static class User implements Serializable
{
public int id;
public String firstName;
public String lastName;
public User() {
}
public User(int id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
#Override
public String toString() {
return String.format("User(%d, %s, %s)", id, firstName, lastName);
}
}
private final Persistit db;
public IndexDemo() throws PersistitException {
Configuration c = new Configuration();
c.getBufferPoolMap().get(16384).setCount(32);
c.getVolumeList().add(new VolumeSpecification(
"IndexDemo.vol,create,pageSize:16384,initialPages:5,extensionPages:5,maximumPages:100"
));
this.db = new Persistit(c);
}
#Override
public void close() throws PersistitException {
db.close();
}
public Exchange userEx() throws PersistitException {
return db.getExchange("IndexDemo", "users", true);
}
public Exchange firstNamesEx() throws PersistitException {
return db.getExchange("IndexDemo", "firstNames", true);
}
// Save the user, both primary and secondary firstName index
public void saveUser(User u) throws PersistitException {
Exchange ex = userEx();
// Primary entries: key of ID and value of full User
ex.getKey().append(u.id);
ex.getValue().put(u);
ex.store();
// First name index: key of (name,ID)
ex = firstNamesEx();
ex.append(u.firstName).append(u.id);
ex.store();
}
// Look-up the user by ID
public User userByID(int id) throws PersistitException {
Exchange ex = userEx();
// Construct and fetch our key
ex.getKey().append(id);
ex.fetch();
// Careful: may not exist
if(!ex.getValue().isDefined()) {
return null;
}
// Otherwise get it from the value
return (User)ex.getValue().get();
}
// Index scan for users with firstName, look-up and return all matches
public List<User> usersByFirstName(String firstName) throws PersistitException {
List<User> users = new ArrayList<>();
Exchange ex = firstNamesEx();
// Iterate over only entires matching firstName
ex.append(firstName).append(Key.BEFORE);
while(ex.next()) {
// Index to second component (id) and decode
int id = ex.getKey().indexTo(1).decodeInt();
// And lookup the user
users.add(userByID(id));
}
return users;
}
public static void main(String[] args) throws PersistitException {
try(final IndexDemo demo = new IndexDemo()) {
System.out.println("No Transaction:");
runDemo(demo);
}
try(final IndexDemo demo = new IndexDemo()) {
System.out.println("Transaction:");
demo.db.getTransaction().run(new TransactionRunnable() {
#Override
public void runTransaction() throws PersistitException {
runDemo(demo);
}
});
}
}
public static void runDemo(IndexDemo demo) throws PersistitException {
demo.saveUser(new User(1, "John", "Doe"));
demo.saveUser(new User(2, "John", "Smith"));
demo.saveUser(new User(3, "Sally", "Jones"));
System.out.println(" User 1: " + demo.userByID(1));
System.out.println(" User 10: " + demo.userByID(10));
System.out.println(" Users named John:");
for(User u : demo.usersByFirstName("John")) {
System.out.println(" " + u);
}
}
}
Running yields this output:
No Transaction:
User 1: User(1, John, Doe)
User 10: null
Users named John:
User(1, John, Doe)
User(2, John, Smith)
Transaction:
User 1: User(1, John, Doe)
User 10: null
Users named John:
User(1, John, Doe)
User(2, John, Smith)
There isn't too much going on:
User POJO with a few attributes
Basic Persistit configuration and start-up
Helpers for saving, look-up by primary/ID and scan by first name
Demo usage of all the helpers
Main runs the demo both inside and outside of a transaction
All the pieces are there for building something extremely simple, like this demo, to something very sophisticated, like a complete SQL server.
Related
I'm kinda confused , about if im storing the Name of the Recipe "TükőrTojás" and the desc of it , because even though, I pass the first test in the add test section, when it comes to , the delete section, the , i fail the first test, my array size changes to 2, I guess its because the name there is already defined ?
Do i have to, somehow, store the already defined name into my Array list?
If i, have to do that , how should i?
public class Recipes {
/*
Implement the Recipes class, which handle food recipes (name, description).
The class should have an add (add a new recipe),
*/
ArrayList<String> recipes = new ArrayList<>();
public void add(String name, String desc)
{ Collections.addAll(recipes,name,desc);
System.out.println(recipes.get(0));
System.out.println(recipes.get(1));
}
public void delete(String name)
{
recipes.remove(name);
}
}
#Test
public void testDelete() {
Recipes recipes = new Recipes();
String name = "Tükörtojás";
recipes.add(name, "1. Az olajat egy serpenyőben kellőképp felforrósítjuk és óvatosan beleütjük" +
" a tojásokat.\r\n2. Keverés nélkül készre sütjük, míg a tojásfehérje megsül, de a sárgája" +
" folyós marad.\r\n3. Hogy jobban átsüljön, a tojásfehérjét egy villa segítségével óvatosan" +
" megmozgathatjuk.");
assertEquals(1, recipes.recipes.size()); // The test i fail
recipes.delete(name);
assertEquals(0, recipes.recipes.size());
}
```
You need to create a JavaBean for Recipe to use it with your ArrayList, so instead of ArrayList<String> you would probably have ArrayList<Recipe>.
RecipeBean.java
For this example I will create a JavaBean named RecipeBean which will contain the Strings recipeName and recipeDescription
public class RecipeBean {
private String recipeName = "", recipeDescription = "";
public RecipeBean() {
}
public String getRecipeName() {
return recipeName;
}
public void setRecipeName(String recipeName) {
this.recipeName = recipeName;
}
public String getRecipeDescription() {
return recipeDescription;
}
public void setRecipeDescription(String recipeDescription) {
this.recipeDescription = recipeDescription;
}
public void clear() {
this.recipeName = "";
this.recipeDescription = "";
}
}
The class above will act as the Recipe object or item for a single Recipe.
Recipe.java
Then in your class called Recipe.class I will declare the ArrayList now with the RecipeBean instead of String for more control.
ArrayList<RecipeBean> recipes = new ArrayList();
import java.util.ArrayList;
public class Recipe {
/*
Implement the Recipes class, which handle food recipes (name, description). The class should have an add (add a new recipe)
*/
ArrayList<RecipeBean> recipes = new ArrayList<>();
/**
* Function to add recipe to recipes ArrayList
*
* #param recipeName - Recipe Name
* #param recipeDescription - Recipe Description
*/
public void addRecipe(final String recipeName, final String recipeDescription) {
System.out.println("Adding recipe : " + recipeName);
RecipeBean recipeBean = new RecipeBean();
recipeBean.setRecipeName(recipeName); // Set recipeName to JavaBean
recipeBean.setRecipeDescription(recipeDescription); // Set recipeDescription to JavaBean
// Check if ArrayList is null
if (recipes != null) {
recipes.add(recipeBean); // Add java bean to ArrayList
}
}
/**
* Function to delete recipe to recipes ArrayList
*
* #param recipeName - Recipe Name
*/
public void deleteRecipe(final String recipeName) {
System.out.println("Deleting recipe : " + recipeName);
// Check if ArrayList is null
if (recipes != null) {
// Loop through ArrayList and remove current object if name matches passed parameter
recipes.removeIf(recipe -> recipe.getRecipeName().equalsIgnoreCase(recipeName));
}
}
}
Hello fellow pragmatic programmers, I have this program which I developed which is a social network program written in java and the main functions of this program is to allow the user to: add a friend, delete friend, see who has the most friends, see who has the most high influence and the ability to exit out of the program.
As with any programs there will be a blip or two, for me it is a case of the java runtime exception this keeps of propping up after I tried to remedy the problem by seeing if it will work without the main package or if I tried to change the way I have written the program to no avail.
This is the error message that keeps on propping up:
Select:
[1] Add Friend
[2] Delete Friend
[3] List Friends
[4] Friends of Friends
[5] Most Popular
[6] Most Influencer
[7] Exit
7
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - Erroneous tree type: uelbook.Person
at uelbook.UELbook.main(UELbook.java:20)
Line 20 of my main class which is UELbook which is down below is:
Person listfriends=new Person();
UELbook:
package uelbook;
import java.util.*;
import java.io.*;
public class UELbook {
public static void main(String[] args) {
UELbook uelbook = new UELbook();
//test your code here
Scanner scanner=new Scanner(System.in);
System.out.println("Select:");
System.out.println("[1] Add Friend");
System.out.println("[2] Delete Friend");
System.out.println("[3] List Friends");
System.out.println("[4] Friends of Friends");
System.out.println("[5] Most Popular");
System.out.println("[6] Most Influencer");
System.out.println("[7] Exit");
int choice=scanner.nextInt();
Person listfriends=new Person();
while(choice!=7){
int num=0;
//ADD
if(choice==1){
System.out.println("ID: ");
String id=scanner.nextLine();
System.out.println("Username: ");
String username=scanner.nextLine();
System.out.println("Password: ");
String password=scanner.nextLine();
listfriends.set(id, username, password);
listfriends.addFriend();
}
//DELETE
if(choice==2){
System.out.println("ID: ");
String id=scanner.nextLine();
System.out.println("Username: ");
String username=scanner.nextLine();
System.out.println("Password: ");
String password=scanner.nextLine();
listfriends.set(id, username, password);
listfriends.removeFriend();
}
//LIST
if(choice==3){
for(int i=0;i<1;i++){
System.out.println(listfriends.list);
}
}
System.out.println("ID: ");
String id=scanner.nextLine();
System.out.println("Username: ");
String username=scanner.nextLine();
System.out.println("Password: ");
String password=scanner.nextLine();
//REMOVE
if(choice==7){
System.exit(0);
}
if(choice==8){
System.out.println("ERROR! Please choose from the options.");
}
}//WHILE LOOP EXIT
}
public void addPerson(String id, String firstname, String lastname) throws PersonExistsException {
//list.add(ID);
// list.add(firstname);
//list.add(lastname);
}
public String getPerson(String id) throws NoSuchCodeException {
return id;
}
public void addFriendship(String id1, String id2) throws NoSuchCodeException {
id1=id1;
id2=id2;
}
public Collection<String> listFriends(String id) throws NoSuchCodeException {
return null;
}
public Collection<String> friendsOfFriends(String id) throws NoSuchCodeException {
return null;
}
//The methods returns true if the file has been loaded,
//false in case of any errors
public boolean loadFile(String file) {
return false; // remove this in the implementation
}
//The methods returns true if the file has been saved,
//false in case of any errors
public boolean saveFile(String file) {
return false; // remove this in the implementation
}
public String mostPopular() {
return null; // remove this in the implementation
}
public String mostInfluencer() {
return null; // remove this in the implementation
}
}
Person:
package UELbook;
import java.util.*;
import java.io.*;
public class Person {
String ID;
String firstname;
String lastname;
ArrayList<String>list=new ArrayList<String>();
public static void main(String[]args){
}
//CONSTRUCTOR
public void set(String ID, String firstname, String lastname){
setID(ID);
setFirstName(firstname);
setLastName(lastname);
}
//SETTERS
public void setID(String ID){
ID=ID;
}
public void setFirstName(String FirstName){
firstname=FirstName;
}
public void setLastName(String LastName){
lastname=LastName;
}
//GETTERS
public String getID(){
return ID;
}
public String getFirstName(){
return firstname;
}
public String getLastName(){
return lastname;
}
public void addPerson(String id, String firstname, String lastname) throws uelbook.PersonExistsException {
list.add(ID);
list.add(firstname);
list.add(lastname);
}
}
Person Exists Exception:
package uelbook;
#SuppressWarnings("serial")
public class PersonExistsException extends Exception {
}
No Such Code Exception:
package uelbook;
#SuppressWarnings("serial")
public class NoSuchCodeException extends Exception {
}
Any helpful hints will be much appreciated.
Your Person class is using package UELbook.
Presumably that should be uelbook.
(Updated to provide an explanation....)
It is only a convention (though followed 99.99% of the time) that the package name should be in all lower case. Oracle states the following as the reason for this:
Package names are written in all lower case to avoid conflict with the
names of classes or interfaces.
In the code in the OP there is:
A package named UELbook
Another package named uelbook
A class named UELbook
So you are getting a clash between class UELbook and package UELbook. Changing the package name UELbook to uelbook should fix your problem from a technical perspective. However, as a related issue, after that you should change the name of your package uelbook or your class UELbook to remove all ambiguity.
I need to make a method getUserById witch will return 1 user by its id. I think that I need to use HashMap so here is my method :
public class UserDao {
private static final String SELECT_USERS = "select * from users_Alana";
public static List<User> getUsers(JdbcTemplate jdbcTemplate){
return jdbcTemplate.query(SELECT_USERS,new UserMapper());
}
private static class UserMapper implements RowMapper<User> {
#Nullable
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User user = new User();
user.setId(resultSet.getInt("id"));
user.setName(resultSet.getString("name"));
user.setGender(resultSet.getString("gender"));
user.setAge(resultSet.getInt("age"));
return user;
}
}
public static void getUserById(int number) throws SQLException {
HashMap<Integer,User> getUser = new HashMap<Integer, User>();
if (getUser.containsKey(number)) {
System.out.println(getUser);
}
}
}
I call this method in a main class by UserDao.getUserById(2); Also I have a class User (with int id, age; String name, gender;) Constructor, getters and setters in it.
The result is nothing. How to solve it?
To get the user by id, I don't think you need a HashMap you can just use :
public static void getUserById(int id) throws SQLException {
UserDao dao = new UserDao();
List<User> users = dao.getUsers(jdbcTemplate);//This return a List or users
User user = user.stream()
.filter(u -> u.getId() == id)// filter the user by id
.findFirst()// if find then return the first
.orElseGet(User::new);// else return new User()
}
But it can be better to create a second query to get user by id :
private static final String SELECT_USERS_BY_ID = "select * from users_Alana WHERE id = ?1";
You need to return the User object from the getUser
public static User getUserById(int number) throws SQLException {
HashMap<Integer,User> getUser = new HashMap<Integer, User>();
return getUser.get(number);
}
You do need to populate the HashMap with the values though
Im try to insert data into Database using ArrayList.there is a Erro msg.
That is my Custmer.class method. this is what i got from when i going to pass ArrayList into another class.
incompatible types: ArrayList<String> cannot be converted to ArrayList<Inquiries>
I want to know how to do this using correct Using OOP concept
public void passingMsg(ArrayList<Inquiries> arrlist){
try {
System.out.println("Method "+arrlist);
String sq = "INSERT INTO Inquiries (name,mail,tp,msg)VALUES(?,?,?)";
PreparedStatement pr = con.prepareStatement(sq);
for(int i=0;i<arrlist.size();i++){
pr.setString(1,arrlist.get(i).getName());
pr.setString(2,arrlist.get(i).getMail());
pr.setString(3,arrlist.get(i).getTp());
pr.setString(4,arrlist.get(i).getMsg());
}
pr.executeQuery();//executeBatch();
} catch (SQLException ex) {
}
}
and this is how i get values from user
String name = txtName.getText();
String mail = txtEmail.getText();
String tp = txtTp.getText();
String msg = txtMsg.getText();
ArrayList<String> arrInq = new ArrayList<String>();
arrInq.add(name);
arrInq.add(mail);
arrInq.add(tp);
arrInq.add(msg);
Custmer c =new Custmer();
if( c.passingMsg(arrInq)){
try {
JOptionPane.showMessageDialog(this, "Successs!!");
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Unsuccesss!!");
e.printStackTrace();
}
}
and this is my Inquiries.class :
public class Inquiries {
private String name;
private String mail;
private String tp;
private String msg;
public Inquiries(String name,String mail,String tp,String msg){
this.name = name;
this.mail = mail;
this.tp = tp;
this.msg = msg;
}
//
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getTp() {
return tp;
}
public void setTp(String tp) {
this.tp = tp;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
Can Some one please explain whats wrong with this. please ?
Reason For Error
This was simply telling you that your types were incompatible for the operation you were trying to perform. In your passingMsg() method, you have its header as: public void passingMsg(ArrayList<Inquiries> arrlist). However, inside your "how i get values from user" area, which I will now refer to as "2nd Snippet", you have your method call declared as: if( c.passingMsg(arrInq)). This means that you are implying that your parameter being passed, arrInq in this case, is of the type ArrayList<Inquiries>, but it's not. It's being initialized in your 2nd Snippet as: ArrayList<String> arrInq = new ArrayList<String>();
Simple Fix
I take no responsibility for this code; use at your own risk. To fix this, you would want to change that entire 2nd Snippet to something similar to the following:
String name = txtName.getText();
String mail = txtEmail.getText();
String tp = txtTp.getText();
String msg = txtMsg.getText();
ArrayList<Inquiries> arrInq = new ArrayList<Inquiries>();
arrInq.add(new Inquiries(name, mail, tp, msg));
Custmer c = new Custmer();
try {
c.passingMsg(arrInq);
JOptionPane.showMessageDialog(this, "Successs!!");
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Unsuccesss!!");
e.printStackTrace();
}
You would also want to change the method header to either return a boolean, or fix it up a little bit to actually throw the exception. Such as:
public void passingMsg(ArrayList<Inquiries> arrlist) {
System.out.println("Method " + arrlist);
String sq = "INSERT INTO Inquiries(name,mail,tp,msg) VALUES(?,?,?)";
PreparedStatement pr = con.prepareStatement(sq);
for (Inquiries inquiries : arrlist) {
pr.setString(1, inquiries.getName());
pr.setString(2, inquiries.getMail());
pr.setString(3, inquiries.getTp());
pr.setString(4, inquiries.getMsg());
}
pr.executeQuery();//executeBatch();
}
Let's talk in O-O-P way.
Here Inquiries is your model, model is nothing but simple class that has instance members and public methods to get and set value of model's instance variable.
Generally we put all database related operations code in their respective models.
e.g. I have model "Model" which typically maps to database table say it as "TableModel" ,I would do something like this:
public class Model{
private int id;
private String attr;
//other properties of the model
public int getId(){
return id;
}
public void setId(int id){
this.id=id;
}
//other getters and setters
//here we write methods to performs database operations
public void save(){
//use "this" to get properties of object
//logic to save to this object in database table TableModel as record
}
public void delete(int id){
//logic to delete this object i.e. from database table TableModel
}
public Model get(int id){
//retrieve record from table TableModel with this id
}
//other methods to get data from database.
}
Now question is how I can use this in some another class. Let's say I have list of Model objects and I wish to insert them in to database.I will do it something like this:
public class AnotherClass{
public void someMethod(){
//create list of models objects e.g. get them from user interface
ArrayList<Model> models=new ArrayList<>();
for(int i=0;i<3;i++){
Model model=new Model();
model.setId(i);
model.setAttr("attr"+i);
models.add(model);
}
SomeOtherClass obj=new SomeOtherClass();
obj.insert(models);
}
}
public class SomeOtherClass{
//other code above.....
//my method that inserts each Model object in database
//Note: this is sample method , you should do it in optimized way
// e.g. batch insert
public void insert(ArrayList<Model> models){
for(Model myModel:models){
myModel.save();
}
}
//other code below.....
}
You are using the wrong type parameter for the ArrayList. Instead of ArrayList<String> you need ArrayList<Inquiries>. To fix the problem, you should remove this code ...
ArrayList<String> arrInq = new ArrayList<String>();
arrInq.add(name);
arrInq.add(mail);
arrInq.add(tp);
arrInq.add(msg);
... and replace it with this code:
ArrayList<Inquiries> arrInq = new ArrayList<Inquiries>();
arrInq.add(new Inquiries(name, mail, tp, msg));
I am learning Eclipse Scout... I have connected to Sql server, fetching data using Object[][]...now, I want to fetch data using beans, beanarray holder...
I dont know the process...
I have created bean Users!
I have populated bean using service, using this example: http://www.eclipse.org/forums/index.php/t/310526/
So can someone explain how to use beans in scout, to populate table, or form...
Make a bean example: users
Fill the bean in service example: get user data from users table
populate table using that bean...
tnx
Java POJO (bean)
If you are working with plain old java object (POJO) like this:
public class User {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
You can populate an array of those POJO like this:
public User[] loadAll() throws ProcessingException {
BeanArrayHolder<User> beansArray = new BeanArrayHolder<User>(User.class);
SQL.selectInto(" select first_name, last_name " +
" from users " +
" into :{FirstName}, :{LastName} ", beansArray);
return beansArray.getBeans();
}
To populate your table, you need to do it by hand. For example on the client side:
for (User user : beansArray.getBeans()) {
ITableRow row = getTable().createRow();
getTable().getNameColumn().setValue(row, user.getLastName());
getTable().getFirstNameColumn().setValue(row, user.getFirstName());
getTable().addRow(row, true);
}
A mapping server side is also possible. But in this case, you should definitively consider to use table data (see the next section)
Table data
You should ensure that you are using bean based TableData. Read this answer to know how you can differentiate table based TableData and bean based TableData.
Assuming you have a UserTableField like this in your Form:
#Order(10.0)
#FormData(sdkCommand = FormData.SdkCommand.USE, value = AbstractTableFieldBeanData.class, defaultSubtypeSdkCommand = FormData.DefaultSubtypeSdkCommand.CREATE)
public class UserTableField extends AbstractTableField<UserTableField.Table> {
#Order(10.0)
public class Table extends AbstractExtensibleTable {
public LastNameColumn getLastNameColumn() {
return getColumnSet().getColumnByClass(LastNameColumn.class);
}
public FirstNameColumn getFirstNameColumn() {
return getColumnSet().getColumnByClass(FirstNameColumn.class);
}
#Order(10.0)
public class FirstNameColumn extends AbstractStringColumn {
#Override
protected String getConfiguredHeaderText() {
return TEXTS.get("FirstName");
}
}
#Order(20.0)
public class LastNameColumn extends AbstractStringColumn {
#Override
protected String getConfiguredHeaderText() {
return TEXTS.get("LastName");
}
}
}
}
You should be able to do something like that in your service:
UserTableRowData rowData = formData.getUserTable().addRow();
rowData.setFirstName("John");
rowData.setLastName("Smith");
Instead of adding the rows manualy, if you want to have a SQL query to populate the table, you can do something like that:
BeanArrayHolder<User> beansArray = new BeanArrayHolder<User>(User.class);
SQL.selectInto(" select first_name, last_name " +
" from users " +
" into :{UserTable.FirstName}, :{UserTable.LastName} ", formData);
It works the same way for TablePageData, see an example in our tutorial:
MiniCrm Tutorial > Write the first page > Load data on the server