O O D B Design And Implementation - O D B Connect -

Joe

Thành viên VIP
21/1/13
2,701
1,246
113
Hi

(cont. of Part 4)

OODB Design and Implementation: ODBConnect
The bugs of GZIPInputStream-ByteArrayInputStream took me two days to find out and to work out for the by-pass solution. The bugs come up when the data (of byte array) are larger than the internal buffer of GZIP subclasses (InflaterInputStream, etc.) and it's around 8KB. What a stupid thing.

We have to some raw ideas what the clients need and what the server has to provide. Their infrastructures determine our ODB design and implementation. On the Client site we have to design an API that allows the clients easily to access the databases.
  • The design must shield them from cumbersome establishment of communication/network. Meaning they need only to know the HostName (or IP) and its Port (number) -and that's all for the establishment of communication/network.
  • The clients need only to know their userID and Password
  • Power users can extend the basic API to their own development for whatever purposes (e.g. DataMining).
  • The familiar "working" environment as they know in their RDB world such as "lock", "commit", etc.
  • The methods must be simple and clear.
  • The users must not know where the data are stored (in a Distributed Database environment)

Example with ODBConnect
PHP:
  ...
  String dbName = "employees";
  ODBConnect odbc = null;
  try {
    odbc = new ODBconnect(host, port, pw, uID);
    odbc.connect(dbName);
    System.out.println(dbName+" is connected.");
  } catch (Exception ex) {
    System.out.println("Exception:"+ex.toString());
    System.exit(0);
  }
  ...
  ArrayList<String> list = odbc.getKeys(dbName);
  System.out.println("List of employees:");
  for (int i = 0, sz = list.size(); i < sz; ++)
    System.out.println((i+1)+". "+list.get(i));
  Employee joe = (Employee) odbc.read(dbName, "Joe");
  if (odbc.lock(dbName, "Joe")) { // lock Key "Joe"
    joe.address = "Mas Les Mimosaa";
    odbc.update(dbName, joe);
    if (!odbc.unlock(dbName, "Joe")) {
      System.out.println("Troubles with unlock()");
      System.exit(-1);
    }
    obdc.commit(dbName, "Joe");
  } else {
    System.out.println("Someone locks the key: Joe");
  }
  ...
The excerpt shows you:
  • how to start a connection to ODB server
  • how to connect to a certain database (here: employee). Note that ODBConnect allows you to connect MORE than ONE database.
  • how to retrieve the keys (accessing keys)
  • how to read a certain object (here: employee "Joe")
  • how to lock this object before it is updated
  • how to update an object
  • how to unlock (or free) the object
  • how to make it permanent (i.e. commit)
Different to some RDBs I've decided to allow one ODBConnect for multiple Databases. The access happens upon the dbName and the key. Further: an ODB can contain different, unrelated objects. The determination of object is in JAVA fashion: casting and instanceof
PHP:
  Object obj = odbc.read(dbName, key):
  if (obj instanceof Employee) {
    ...
  } else if (obj instanceof Animal) {
    ...
  } else if (obj instanceof String) {
    System.out.println("It's a String:"+(String)obj);
  }
Example:
1) Object Member:
PHP:
public class Member implements java.io.Serializable {
  private static final long serialVersionUID = 1234567890L;
  private int age;
  private double salary;
  private String name, address;
  public Member(String name, int age, String address, double salary) {
    this.age = age;
    this.name = name;
    this.address = address;
    this.salary = salary;
  }
  public String toString() {
    return "Name:\t"+name+"\nAge:\t"+age+"\nAddr.:\t"+address+"\nSalary:\t"+salary;
  }
  public void print() {
    System.out.println("Name:\t"+name+
         "\nAge:\t"+age+
         "\nAddr.:\t"+address+
         "\nSalary:\t"+salary);
  }
}
2) Object Animal:
PHP:
public class Animal implements java.io.Serializable {
  private static final long serialVersionUID = 1234L;
  private ImageIcon img;
  private double weight;
  private String name, pic;
  public Animal(String name, String pic, double weight) {
    this.pic = pic;
    this.name = name;
    this.weight = weight;
  }
  public ImageIcon getImage( ) {
    if (pic.indexOf("://") < 0 && (new File(pic)).exists()) return new ImageIcon(pic);
    try {
      return new ImageIcon(new URL(pic));
    } catch (Exception e) { }
    return null;
  }
  public void setWeight(double w) {
    weight = w;
  }
  public String toString() {
    return "ZooAnimal:"+name+" has a weight "+weight+"Kg. Image@pic:"+pic;
  }
  public void print() {
    System.out.println("ZooAnimal:"+name+" has a weight "+weight);
  }
  public void print(OutputStream out) {
    try {
      out.write(("ZooAnimal:"+name+" has a weight "+weight).getBytes());
      out.flush();
    } catch (Exception e) {
      System.out.println("Troubles with OutputStream out");
    }
  }
  public void show(JFrame jf) {
    new Display(jf, getImage( ));
  }
  //
  private class Display extends JDialog {
    public Display(JFrame jf, ImageIcon icon) {
      super(jf, true);    
      setImage(jf, icon);
    }
    private void setImage(JFrame jf, ImageIcon img) {
      setTitle("Animal:"+name);
      setDefaultCloseOperation(DISPOSE_ON_CLOSE);
      JButton but = new JButton(img);
      but.setContentAreaFilled(false);
      but.setBorderPainted(false);
      add(but, BorderLayout.CENTER);
      setSize(img.getIconWidth()+40, img.getIconHeight()+40);
      //
      setLocationRelativeTo(jf);
      setVisible(true);
    }
  }
}
3) Object "String"

And the codes could be as following:
PHP:
      ...
      try {
        String dbName = "OODBmix";
        //                                   host      port     pw       uID
        ODBConnect dbcon = new ODBConnect("localhost", 12345, "tester", "test");
        dbcon.connect(dbName); // openDB
        System.out.println("Open: "+dbName);
        String ID = dbcon.getID(); // UserID
        ArrayList<String> keys = odbcon.getKeys(dbName);
        java.util.Random ran = new java.util.Random();
        //
        String key = keys.get(ran.nextInt(keys.size()));
        Object obj = dbcon.read(dbName, key);
        if (dbcon.lock(dbName, key)) {
          if (obj instanceof Member) dbcon.update(dbName, key, (Member)obj);
          else if (obj instanceof Animal) dbcon.update(dbName, key, (Animal)obj);
          else if (obj instanceof String) dbcon.update(dbName, key, (String)obj);
          else {
            System.out.println("User:"+ID+" locked '"+key+"', updated but Object was corrupted");
            return;
          }
          bool = dbcon.unlock(dbName, key);
          if (bool)
            System.out.println("User:"+ID+" locked '"+key+"', updated and unlocked.");
          else System.out.println("User:"+ID+" locked '"+key+"', updated but unlock failed.");
        } else {
          System.out.println(">>>User:"+ID+" locked '"+key+"' but failed");
          return;
        }
        ...
      } catch (Exception ex) {
        ex.printStackTrace();
        System.exit(-1);
      }
      ...
The source of the API ODBConnect will be bundled and released when this series terminates

(Next: OODB Design and Implementation: ODBWorker)
 
Sửa lần cuối: