My first trail: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(22 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''SaaS - 3.10. - Databases and migrations'''
<p>A Database<ref>http://en.wikipedia.org/wiki/Database</ref> is a coherent collection of data with inherent meaning. Random assortment of data is not a database. Data is organized in order to model relevant aspects of reality, so that it supports processes requiring this data. Data Migration is related to transfer of data between storage types, formats, or computer systems. This is performed programmatically to accomplish an automated migration so that humans are free from doing this repetitive task.</p>


== Introduction ==


Object oriented programming is a [http://en.wikipedia.org/wiki/Programming_paradigm programming paradigm] using "objects" – usually instances of a class – consisting of data fields and methods together with their interactions to design applications and computer programs. In static object orientation, this instantiation is static, that is the class to which an object belongs is defined before the execution of the code. This gives a strong binding of the objects, and ensures that the correct instance variables and methods are accessed by that object. In Dynamic object orientation, also known as interpreted object orientation, there is no fixed type. The type the object belongs to is determined during runtime, hence that gives additional flexibility. Static typing should be used where possible, dynamic typing when needed.
== Database ==
<p>
A database is nothing more than a collection of meaningful information. Databases can be of multiple types, for example Distributed Databases, Relational Databases, Flat File Databases. A database could be as simple as a text file with a list of names or it can even be very complex as a large relational database management system
<br/>
Examples:
<ol>
<li>    Banking Systems where accounts are maintained and it is made sure that money does not disappear as a result of system failure.</li>
<li>    Airline Reservation Systems where the plane details, the airport details and the customer details are maintained.</li>
<li>  Hotel Management Systems where the availability of rooms, the rates and the customer details are maintained.</li></ol></p>


== JRuby ==
== Data Migration ==


[http://en.wikipedia.org/wiki/JRuby JRuby] is the Ruby Programming Language on the [http://en.wikipedia.org/wiki/JVM JVM].  
<p>
Ruby is a reflective, dynamic, and interpreted object-oriented scripting language. JRuby is a Java programming language implementation of the Ruby language syntax with all the core libraries plus the  standard libraries. With JRuby, you get all of the advantages of Ruby plus access to the full range of Java platform functionality. This can be achieved using the following two flavors.<br>
Every application in reality has a database in the backend to store all the relevant data of the application. We should not test the application on database because it may contain valuable data like customer information in a banking system. So editing that data present in the database is not a good idea. The solution Rails<ref>http://guides.rubyonrails.org/getting_started.html</ref> provides for above problem is Defining three different environments: Development, Production and Testing each of which has a separate database and appropriate database types.</p><p>
The Development Environment is what we use while developing the application. The production environment refers to the database that is used when the application is published in the real world. The testing environment is meant for testing tools.  Testing of the application is done using Testing tools which automates the entire testing procedure. Since there are different databases in each environment, the problem that occurs is changes made in one Database do not reflect in the other.</p><p>
A programmer is also responsible to tell the other developers what changes have been made in the database. Also one has to keep track of which changes need to be run against production machines during deployment.
The solution for the above problem that rails offers is data migration. Databases of different types can also be migrated between the three different environments. For example, we may use  SQLlite<ref>http://en.wikipedia.org/wiki/SQLite</ref> in Development environment, but we can still migrate into production environment where heroku<ref>http://en.wikipedia.org/wiki/Heroku</ref> may have been used. The source is portable and the backend understands what operations to do on the database.</p>
<p>
In reality Rails migrations are similar to version control<ref>http://betterexplained.com/articles/a-visual-guide-to-version-control/</ref> of databases. Rails migrations is actually used since databases change requires modifications to both code and data. Hence we cannot use a source code version control system like Subversion<ref>http://svnbook.red-bean.com/ </ref> or Sourcesafe.<ref>https://wiki.library.ucsf.edu/display/~128507@ucsf.edu/Source+Safe+vs.+Subversion</ref> 
</p>


* Driving Ruby from Java
== Creating Migrations ==
* Driving Java from Ruby
<p>


Some examples where this integration can be done are:  
A migration is a sub class of ActiveRecord:: Migration which implements two methods: ‘up’ and ‘down’. The “up” method performs the required changes or transformations while the down methods reverses or roll backs them.
 
A migration can be created using the following command:</p>
* From a JRuby script, you can call the Java platform Math library to access its powerful computational capabilities or call the Java platform Swing library to display a dialog box that requires end-user input before allowing the script to proceed. <br>
<pre>
* You can use the [http://en.wikipedia.org/wiki/Scripting_for_the_Java_Platform JSR 223] Scripting APIs or the [http://en.wikipedia.org/wiki/Bean_Scripting_Framework Bean Scripting Framework (BSF)] APIs to call a JRuby script from within a Java application to, for example, invoke back-end processing scripts from a servlet to update or generate web content.  <br>
 
== Difficulties in mixing static and dynamic object oriented code ==
 
There can be some issues in mixing static and dynamic object oriented code.
 
* If the static object oriented code makes use of generics.<br> For example, in case we are using Java, the generic types are erased during compilation for backward compatibility. As a result for a dynamically types language like Ruby, there will be problems with type conversion.For example, if you have a Map<String,String>, it will be seen as a simple Map, and JRuby will not be able to determine the correct types using reflection.<br>
* If you have a class name ambiguity between Java and Ruby.<br> In such a case, the class name will reference the Ruby construct within the Ruby code. For instance, if you import java.lang.Thread and then write JThread < Thread, JThread will in fact inherit the Ruby Thread object, not the Java Thread. The solution is to use the full Java Class name, such as: JThread < java.lang.Thread<br>
* Java classes can't inherit from a JRuby class. Hopefully this feature will be added in the planned re-write of the Java integration layer in a future release of JRuby.
* JRuby automatically binds the following names in the context of a class to the top-level Java packages: com, org, java, javax. This means that you can reference these packages without having to explicitly require or import them. This takes effect for all Ruby classes in an application where a require 'java' appears. If you do not want this behaviour for a specific class, you have to undefine it for that class.
 
== Advantages of JRuby ==
 
=== Advantages of JRuby over Ruby ===
 
* With JRuby you get the best of both worlds: Ruby applications and libraries, plus Java libraries. <br>
* Code can be fully compiled ahead of time or just in time. <br>
* In addition to the native libraries you can access Java libraries with Ruby syntax (or Java syntax, if you want).  <br>
* JRuby runs faster than Ruby, except at startup.[http://blog.dhananjaynene.com/2008/07/performance-comparison-c-java-python-ruby-jython-jruby-groovy]
 
=== Advantages of JRuby over Java ===
 
* Ruby is powerful. Ruby code is easy to understand. <br>
* Ruby has the following good features which are missing from Java. <br>
**[http://en.wikipedia.org/wiki/Closure_(computer_science) Closure (blocks)] <br>
**[http://en.wikipedia.org/wiki/Meta_programming Meta programming] <br>
**[http://en.wikipedia.org/wiki/Duck_typing Duck-typing] <br>
**[http://en.wikipedia.org/wiki/Domain_Specific_Language Domain Specific Language] (DSL).
 
== JRuby Explained ==
In addition to the advantages mentioned in the above section, some other features of JRuby are:
*Reopening Java Classes<br>In Ruby, classes are always open, which means that you can later add methods to existing classes. This also works with Java classes. This comes in handy when adding syntactic sugar like overloaded operators to Java classes, or other methods to make them behave more Ruby-like. Note that these additions will be visible only on the JRuby side.
*Mixing Java Interfaces <br> JRuby classes can now implement more than one Java interface. Since Java interfaces are mapped to modules in JRuby, you implement them not by subclassing, but by mixing them in.
*Exception handling <br> Native Java exceptions can be caught and thrown in Ruby code.
*Synchronization <br> When interacting with Java APIs from JRuby, it is sometimes necessary to synchronize on an object for thread safety. To support this functionality, in JRuby, a synchronize method is provided on every wrapped Java object.
 
Let us see the two implementations of JRuby.
 
===<b> Driving Java from Ruby</b>===
This involves calling Java methods from Ruby code. This includes adding some Java functionality in the Ruby code. The final code will be run on the JVM. Ruby code can load and interact with Java libraries. As a simple example we can use an ArrayList from Java and integrate it with the Ruby code as seen below:


rake generate migration CreateCourse
</pre>
Migration Created :
<pre>
<pre>
require ‘java’
class CreateCourse < ActiveRecord::Migration
 
def up
list = java.util.ArrayList.new
create_table :course do |t|
 
  t.string :name
list << ‘List of’
  t.text :description
list << 3
  t.timestamps
list << :assorted_items
end
 
end
list.each do |item|
def down
puts “#{item.class}: #{item}”
drop_table :course
end
end
end
</pre>
</pre>
<p>


Instead of just requiring a specific class you can also require the entire package. This can be done as follows:
The above migration CreateCourse has just been created, but has not been applied to the Database yet. This migration will add a table called courses with string column called name and the text column called description. A primary key column called id will also be created by default. The time stamp columns created_at and updated_at which ActiveRecord populates automatically will also be added. Reversing this migration is nothing but dropping the table.</p>
 
<p>
Migrations can also be used to fix bad data in the database or generate new fields.<br />
For Example:
<pre>
<pre>
module JavaLangDemo
class AddGradesToStudents < ActiveRecord::Migration
  include_package "java.lang"
def up
  # alternately, use the #import method
change_table :students do |t|
  import "java.lang"
  t.boolean :receive_grade, :default => false
end
User.update_all ["receive_grade = ?", true]
end
def down
remove_column :students, :receive_grade
end
end
end
</pre>
</pre>
The above migration adds receive_grades to the students table. We want the default value to be false for new students. But existing students are considered to have a grade, So we use the student model to set the flag to true for existing students.</p>
<p>
ActiveRecord<ref>http://api.rubyonrails.org/classes/ActiveRecord/Base.html</ref> provides methods that perform common data definition tasks in a database. A migration is like a Ruby class so you’re not limited to these functions. For example, after adding a column you can write a code to set the value of that column for existing records (if necessary using your models).  The kind of object that  is yielded as a result of the migration code is object representing table.


One has to be careful in doing this as name conflicts in both Ruby and Java can result in losing the Ruby functionality. For example, if a File object is created using Java’s java.io.File class, then the Ruby constant File becomes useless.
</p>
 
<pre>
import java.io.File
newfile = File.new("file.txt")
</pre>
and then using:


<pre>
=== OODSL compiler for FPGA ===
File.open('README', 'r') {|f| puts f.readline }
An object oriented domain specific compiler was developed for programming Field Programmable Gate Arrays.<ref>Object-Oriented Domain Specific Compilers for Programming FPGAs[http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=920835&userType=inst&tag=1]</ref> The compiler allows the hardware programmer to make use of object-oriented style while programming. The research paper claims that this way of programming the hardware brings down the time taken for design by several notches and still results in good optimal performance.
</pre>


This will give the error - NoMethodError: private method `open' called for Java::JavaIo::File:Class
== Tools for Creating OODSL ==
When creating an OODSL, one can either choose to start from scratch or use a tool that is already available. Creating a language from scratch gives the programmer a certain amount of flexibility to define it the way he wants to, but it takes a lot of time. Therefore, in general, software tools are used to aid in the process of creating Domain Specific Languages. This is because it not only saves time, but also helps to make the language easy to use due to familiarity with the syntax of the underlying language.
=== Boo ===
Boo<ref>Boo Home[http://boo.codehaus.org/Home]</ref> is an open source object oriented language that is used to create Domain Specific languages. Defining basic data structures like array, hash, variables etc are inherently supported in Boo and it makes their creation easier. Although Boo is a statically typed language, these restrictions can be bent once in a while so that the type of objects can be found and manipulated in run time as well ([http://en.wikipedia.org/wiki/Duck_typing <code>Duck typing</code>]).


This situation can be avoided by including the package in the module definition and then using that module scope to create a new file using the File object.
=== Visual Studio ===
Visual Studio has Domain-specific language tools that are designed to help the designer to build a language focusing on the language grammar and characteristics rather than paying much attention to the internal details of the compiler.<ref>Domain specific development[http://www.domainspecificdevelopment.com/]</ref> Visual tools are used that help focus on the business requirements of the OODSL rather than worrying about how it works internally.
=== Groovy ===
Groovy <ref>Groovy Home[http://groovy.codehaus.org/]</ref> is a dynamic language for the Java Virtual Machine. Also, the syntax is groovy is similar to that of Java, making designing of new OODSLs easier and similar to programming in Java. [http://java.dzone.com/articles/groovy-dsl-simple-example<code>An example for developing an OODSL in Groovy</code>].


<pre>
== OODSL vs. non-OODSL ==
newfile = JavaIO::File.new("file.txt")
When defining a DSL, choosing whether to go with an OODSL or a non-OODSL depends on several factors like the domain for which it is defined, existing DSLs for that domain etc. Non-OODSLs are domain specific languages that do not necessarily embrace object oriented concepts like abstraction, polymorphism etc. OODSLs can be well suited for some situations whereas in other situations, they might be an overkill. Defining a new OODSL when there is an already widely accepted non-OODSL may not be very useful. For example, HTML is the standard method for displaying web pages and it is non-OODSL. Defining a new non-OODSL that replaces HTML may not prove to be significantly advantageous.
</pre>


JRuby will forward any option to the underlying Java runtime if you preface it with -J.
== Advantages and Disadvantages ==
Some of the advantages of OODSLs would be:
* Since OODSLs, by their name, are object oriented, they give the developer an easier alternative to model their applications based on business goals and using real world paradigms.
* Because of their object oriented nature, the code is generally simple to understand and therefore code maintenance would be easier in OODSLs than in non-OODSLs.
* Object oriented concepts like encapsulation and abstraction give the code better security when they are modified in the future.


===<b>Driving Ruby from Java</b>===


There are three ways for using the JRuby Interpreter from Java namely, Embedding JRuby, using JSR 223 and the Bean Scripting Framework.  
Though OODSLs in general have several advantages over other languages, one must also consider their disadvantages:
* Defining an object oriented language in general takes more time than defining a normal language because we have to properly define it to include OO concepts.
* They may not be well-suited for all domains and environments. Sometimes there may be a simpler non-OODSL way to achieve the task.


====<b>Embedding JRuby</b>====
== A Running Example ==
Embed Core[https://github.com/jruby/jruby/wiki/DirectJRubyEmbedding] is the main embedding API that ships with JRuby. This API offers a great deal of interoperability. You can call a Ruby method, crunch the results in Java, and hand data back into Ruby. The following code shows an example of embedding Ruby in Java.
Given here is a simple example <ref>Example DSL in groovy[http://java.dzone.com/articles/groovy-dsl-simple-example]</ref> for creating an OODSL. The DSL defined here simply prints the text we have specified in the program. This is defined in [http://en.wikipedia.org/wiki/Groovy_(programming_language)<code>Groovy</code>].


The definition of our new OODSL is as follows:
<pre>
<pre>
import java.util.ArrayList;
package com.solutionsfit.dsl.memotemplate
import org.jruby.Ruby;
import groovy.xml.MarkupBuilder
import org.jruby.RubyRuntimeAdapter;
class MemoDsl {
import org.jruby.javasupport.JavaEmbedUtils;
String toString
 
String fromString
public class MyEmbedRubyExample {
String messageString
    public static void main(String[] args) throws Exception {
def sections = []
      // Create runtime instance
/**
        Ruby runtime = JavaEmbedUtils.initialize(new ArrayList());
* Make a closure. Main definition of the DSL program
        RubyRuntimeAdapter evaler = JavaEmbedUtils.newRuntimeAdapter();
*/
 
def static make(closure) {
        evaler.eval(runtime, "puts 1+2");
MemoDsl memoDsl = new MemoDsl()
 
closure.delegate = memoDsl
        // Shutdown and terminate instance
closure()
        JavaEmbedUtils.terminate(runtime);
}
    }
/**
* Store the values in the local variables
*/
def to(String toString){
this.toString = toString
}
def from(String fromText){
this.fromString = bodyString
}
def message(String messageString){
this.messageString = messageString
}
/**
* The getText method gets called by the DSL by delegation
*/
def getText(){
doText(this)
}
private static doText(MemoDsl memodsl){
String template = "Memo\nTo: ${memoDsl.toText}\nFrom: ${memoDsl.fromText}\n${memoDsl.body}\n"
def sectionStrings =""
for (s in memoDsl.sections) {
sectionStrings += s.title.toUpperCase() + "\n" + s.body + "\n"
}
template += sectionStrings
println template
}
}
}
</pre>
</pre>


To run the above code you need to include jruby.jar in the classpath. This jar is present in the lib folder of the JRuby installation directory. The above example outputs "3" as expected.
A sample program in our newly developed OODSL would be:
 
====<b>JSR 223, Scripting for the Java Platform</b>====
This provides an API framework for calling scripting code from within a Java application and passing data between the application and the script. These features make it possible to combine existing scripts with Java applications and to extend a Java application with general-purpose scripts that other Java applications can also use.
JSR 223 Scripting APIs are available in JDK 6 software, and by default, the APIs support the JavaScript programming language. The JSR 223 Scripting APIs can be used with any JSR 223-compliant scripting engine such as JRuby.
 
The steps are:
*Java integration with Java 6 will be using the standard scripting API (JSR223). A JRuby scripting engine already exists and is located [https://scripting.dev.java.net here]
*Download and unzip the collection of jars from the documents and files section of the site (jsr223-engines.tar.gz or jsr223-engines.zip).Look in the uncompressed files for the jruby/build/jruby-engine.jar file.
*Add this file to your classpath and then use the code below to access the engine.
 
<pre>
<pre>
import javax.script.*;
package com.solutionsfit.dsl.memotemplate
 
public class jrubytry {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager factory = new ScriptEngineManager();
 
        // Create a JRuby engine.
        ScriptEngine engine = factory.getEngineByName("jruby");


        // Evaluate JRuby code from string.
class MemolDslTest extends GroovyTestCase {
        try {
void testDslUsage_outputText() {
            engine.eval("puts('Hello')");
MemoDsl.make {
        } catch (ScriptException exception) {
to "Nirav Assar"
            exception.printStackTrace();
from "Barack Obama"
        }
message "How are things? We are doing well. Take care"
    }
text
}
}
}
}
</pre>
</pre>
The above program prints "Hello".
====<b>The Bean Scripting Framework (BSF)</b>====
This is another way to call scripting code from within a Java application.
The Bean Scripting Framework, when used with JRuby, will allow you to conveniently to pass your own Java objects to your JRuby script. You can then use these objects in JRuby, and changes will affect your Java program directly. To run a JRuby script using BSF, you must first copy the BSF.jar file into your JAVA_HOME/lib/ext/ folder. Then, try the following:
<pre>
import org.jruby.Ruby.*;
import org.jruby.*;
import org.jruby.javasupport.bsf.*;
import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;
{...}
JLabel mylabel = new JLabel();
BSFManager.registerScriptingEngine("ruby",
                                  "org.jruby.javasupport.bsf.JRubyEngine",
                                  new String[] { "rb" });
BSFManager manager = new BSFManager();
/* Import an object using declareBean then you can access it in JRuby with $<name> */
manager.declareBean("label", mylabel, JFrame.class);
manager.exec("ruby", "(java)", 1, 1, "$label.setText(\"This is a test.\")");
</pre>
== Conversion of Types ==
When calling Java from JRuby, primitive Ruby types are converted to default boxed Java types. The table below shows this conversion.
For example if we have a ruby method that returns a string object then we can convert it into a java.lang.String object on the Java side. The table shown below provides a quick overview of the mapping of types:
{| style="background:#FFFFFB; margin-left: 4em;" border="1" cellpadding="4"  cellspacing="0"
  |-
  | <b>Ruby Type</b>||<b> Java Type </b>
  |-
  | "foo" || java.lang.String
  |-
  | 1|| java.lang.Long
  |-
  | 1.0 || java.lang.Double
  |-
  | true, false|| java.lang.Boolean
  |-
  | 1|| java.math.BigInteger
  |}
When primitive Java types are passed to JRuby they are converted to the following Ruby types:
{| style="background:#FFFFFB; margin-left: 4em;" border="1" cellpadding="4"  cellspacing="0"
  |-
  | <b>Java Type </b>||<b> Ruby Type </b>
  |-
  | public String || String
  |-
  | public byte || Fixnum
  |-
  | public short || Fixnum
  |-
  | public char || Fixnum
  |-
  | public int || Fixnum
  |-
  | public float || Float
  |-
  | public double|| Float
  |}
== Difficulties with JRuby ==
<b>Larger memory footprint and startup time - Difficulty over Java. </b>
A single JRuby instance needs more memory than a single Ruby instance, but in a typical production server environment with multiple mongrels, memory can be shared so that we can expect a lower or at least equal memory usage in total. JRuby’s startup time is higher than MRI, but once the JVM has “warmed up” after a few minutes, it usually runs faster than [http://en.wikipedia.org/wiki/Ruby_MRI MRI].
<b>No native C extension - Difficulty over Ruby.</b>
Due to the nature of Java, it is impossible to run any native extension. So there are several gems that don’t work since they rely on a C extension. However, there’s ongoing effort to create alternative gems that are compatible to JRuby. E.g. mongrel uses a native C extension, but if you install the mongrel gem using JRuby, it automatically installs a java-enhanced version.
<b>JRuby is not technically complete</b>
It’s told that there are cases where JRuby is not 100% compatible with MRI. However, big frameworks like Rails are tested with JRuby.
== Conclusion ==
The JRuby interpreter combines Ruby's simplicity and ease of use with Java's extensive libraries and technologies, a potent blend that opens new possibilities for Ruby, Rails, and Java. JRuby combines a lot of advantages of Java and Ruby by enabling us to reopen Java classes, mixing Java interfaces in Ruby, letting JRuby classes implement more than one Java interface by mixing the interfaces in the classes, catching the native Java exceptions and throwing them via Ruby code etc. There are three ways of calling Ruby from Java namely embedding JRuby, using JSR 223 and by using the bean scripting framework and this provides better flexibility to the programmer. Thus mixing static and dynamic code combines the power of dynamic languages with the stability of static languages.


== References ==
== References ==
 
<references/>
#http://blog.dhananjaynene.com/2008/07/performance-comparison-c-java-python-ruby-jython-jruby-groovy<br>
#http://www.javaworld.com/javaworld/jw-07-2006/jw-0717-ruby.html <br>
#http://java.sun.com/developer/technicalArticles/scripting/jruby/ <br>
#http://en.wikipedia.org/wiki/JRuby <br>
#http://rubysource.com/learning-more-about-jruby-from-charles-nutter/ <br>
#https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby <br>
#http://media.pragprog.com/titles/jruby/embed.pdf <br>
#http://www.coderanch.com/t/461625/Ruby/JRuby-benefits <br>
#http://zargony.com/2008/09/26/why-i-m-starting-to-like-jruby-even-though-i-dislike-java <br>
#https://github.com/jruby/jruby/wiki/JavaIntegration#wiki-Java_6_using_JSR_223_Scripting <br>
#https://github.com/jruby/jruby/wiki/DirectJRubyEmbedding <br>
#Kutner, Joe (August 22, 2012), [http://research.microsoft.com/en-us/um/people/emeijer/Papers/RDL04Meijer.pdf Static Typing Where Possible, Dynamic Typing When Needed: The End of the Cold War Between Programming Languages]<br>
 
== Further Reading ==
 
Charles O Nutter, Thomas Enebo, Nick Sieger, Ola Bini, and Ian Dees, Using JRuby: Bringing Ruby to Java, 2011

Latest revision as of 06:44, 3 October 2012

SaaS - 3.10. - Databases and migrations

A Database<ref>http://en.wikipedia.org/wiki/Database</ref> is a coherent collection of data with inherent meaning. Random assortment of data is not a database. Data is organized in order to model relevant aspects of reality, so that it supports processes requiring this data. Data Migration is related to transfer of data between storage types, formats, or computer systems. This is performed programmatically to accomplish an automated migration so that humans are free from doing this repetitive task.


Database

A database is nothing more than a collection of meaningful information. Databases can be of multiple types, for example Distributed Databases, Relational Databases, Flat File Databases. A database could be as simple as a text file with a list of names or it can even be very complex as a large relational database management system
Examples:

  1. Banking Systems where accounts are maintained and it is made sure that money does not disappear as a result of system failure.
  2. Airline Reservation Systems where the plane details, the airport details and the customer details are maintained.
  3. Hotel Management Systems where the availability of rooms, the rates and the customer details are maintained.

Data Migration

Every application in reality has a database in the backend to store all the relevant data of the application. We should not test the application on database because it may contain valuable data like customer information in a banking system. So editing that data present in the database is not a good idea. The solution Rails<ref>http://guides.rubyonrails.org/getting_started.html</ref> provides for above problem is Defining three different environments: Development, Production and Testing each of which has a separate database and appropriate database types.

The Development Environment is what we use while developing the application. The production environment refers to the database that is used when the application is published in the real world. The testing environment is meant for testing tools. Testing of the application is done using Testing tools which automates the entire testing procedure. Since there are different databases in each environment, the problem that occurs is changes made in one Database do not reflect in the other.

A programmer is also responsible to tell the other developers what changes have been made in the database. Also one has to keep track of which changes need to be run against production machines during deployment.

The solution for the above problem that rails offers is data migration. Databases of different types can also be migrated between the three different environments. For example, we may use SQLlite<ref>http://en.wikipedia.org/wiki/SQLite</ref> in Development environment, but we can still migrate into production environment where heroku<ref>http://en.wikipedia.org/wiki/Heroku</ref> may have been used. The source is portable and the backend understands what operations to do on the database.

In reality Rails migrations are similar to version control<ref>http://betterexplained.com/articles/a-visual-guide-to-version-control/</ref> of databases. Rails migrations is actually used since databases change requires modifications to both code and data. Hence we cannot use a source code version control system like Subversion<ref>http://svnbook.red-bean.com/ </ref> or Sourcesafe.<ref>https://wiki.library.ucsf.edu/display/~128507@ucsf.edu/Source+Safe+vs.+Subversion</ref>

Creating Migrations

A migration is a sub class of ActiveRecord:: Migration which implements two methods: ‘up’ and ‘down’. The “up” method performs the required changes or transformations while the down methods reverses or roll backs them. A migration can be created using the following command:


rake generate migration CreateCourse

Migration Created :

class CreateCourse < ActiveRecord::Migration
def up
create_table :course do |t|
   t.string :name
   t.text :description
   t.timestamps
 end
end
def down
 drop_table :course
end
end

The above migration CreateCourse has just been created, but has not been applied to the Database yet. This migration will add a table called courses with string column called name and the text column called description. A primary key column called id will also be created by default. The time stamp columns created_at and updated_at which ActiveRecord populates automatically will also be added. Reversing this migration is nothing but dropping the table.

Migrations can also be used to fix bad data in the database or generate new fields.
For Example:

class AddGradesToStudents < ActiveRecord::Migration
def up
 change_table :students do |t|
   t.boolean :receive_grade, :default => false
 end
 User.update_all ["receive_grade = ?", true]
end
def down
 remove_column :students, :receive_grade
end
end

The above migration adds receive_grades to the students table. We want the default value to be false for new students. But existing students are considered to have a grade, So we use the student model to set the flag to true for existing students.

ActiveRecord<ref>http://api.rubyonrails.org/classes/ActiveRecord/Base.html</ref> provides methods that perform common data definition tasks in a database. A migration is like a Ruby class so you’re not limited to these functions. For example, after adding a column you can write a code to set the value of that column for existing records (if necessary using your models). The kind of object that is yielded as a result of the migration code is object representing table.

OODSL compiler for FPGA

An object oriented domain specific compiler was developed for programming Field Programmable Gate Arrays.<ref>Object-Oriented Domain Specific Compilers for Programming FPGAs[1]</ref> The compiler allows the hardware programmer to make use of object-oriented style while programming. The research paper claims that this way of programming the hardware brings down the time taken for design by several notches and still results in good optimal performance.

Tools for Creating OODSL

When creating an OODSL, one can either choose to start from scratch or use a tool that is already available. Creating a language from scratch gives the programmer a certain amount of flexibility to define it the way he wants to, but it takes a lot of time. Therefore, in general, software tools are used to aid in the process of creating Domain Specific Languages. This is because it not only saves time, but also helps to make the language easy to use due to familiarity with the syntax of the underlying language.

Boo

Boo<ref>Boo Home[2]</ref> is an open source object oriented language that is used to create Domain Specific languages. Defining basic data structures like array, hash, variables etc are inherently supported in Boo and it makes their creation easier. Although Boo is a statically typed language, these restrictions can be bent once in a while so that the type of objects can be found and manipulated in run time as well (Duck typing).

Visual Studio

Visual Studio has Domain-specific language tools that are designed to help the designer to build a language focusing on the language grammar and characteristics rather than paying much attention to the internal details of the compiler.<ref>Domain specific development[3]</ref> Visual tools are used that help focus on the business requirements of the OODSL rather than worrying about how it works internally.

Groovy

Groovy <ref>Groovy Home[4]</ref> is a dynamic language for the Java Virtual Machine. Also, the syntax is groovy is similar to that of Java, making designing of new OODSLs easier and similar to programming in Java. An example for developing an OODSL in Groovy.

OODSL vs. non-OODSL

When defining a DSL, choosing whether to go with an OODSL or a non-OODSL depends on several factors like the domain for which it is defined, existing DSLs for that domain etc. Non-OODSLs are domain specific languages that do not necessarily embrace object oriented concepts like abstraction, polymorphism etc. OODSLs can be well suited for some situations whereas in other situations, they might be an overkill. Defining a new OODSL when there is an already widely accepted non-OODSL may not be very useful. For example, HTML is the standard method for displaying web pages and it is non-OODSL. Defining a new non-OODSL that replaces HTML may not prove to be significantly advantageous.

Advantages and Disadvantages

Some of the advantages of OODSLs would be:

  • Since OODSLs, by their name, are object oriented, they give the developer an easier alternative to model their applications based on business goals and using real world paradigms.
  • Because of their object oriented nature, the code is generally simple to understand and therefore code maintenance would be easier in OODSLs than in non-OODSLs.
  • Object oriented concepts like encapsulation and abstraction give the code better security when they are modified in the future.


Though OODSLs in general have several advantages over other languages, one must also consider their disadvantages:

  • Defining an object oriented language in general takes more time than defining a normal language because we have to properly define it to include OO concepts.
  • They may not be well-suited for all domains and environments. Sometimes there may be a simpler non-OODSL way to achieve the task.

A Running Example

Given here is a simple example <ref>Example DSL in groovy[5]</ref> for creating an OODSL. The DSL defined here simply prints the text we have specified in the program. This is defined in Groovy.

The definition of our new OODSL is as follows:

package com.solutionsfit.dsl.memotemplate
import groovy.xml.MarkupBuilder
class MemoDsl {
	String toString
	String fromString
	String messageString
	def sections = []
	/**
	* Make a closure. Main definition of the DSL program
	*/
	def static make(closure) {
		MemoDsl memoDsl = new MemoDsl()
		closure.delegate = memoDsl
		closure()
	}
	/**
	* Store the values in the local variables
	*/
	def to(String toString){
		this.toString = toString
	}
	def from(String fromText){
		this.fromString = bodyString
	}
	def message(String messageString){
		this.messageString = messageString
	}
	/**
	* The getText method gets called by the DSL by delegation
	*/
	def getText(){
		doText(this)
	}
	private static doText(MemoDsl memodsl){
		String template = "Memo\nTo: ${memoDsl.toText}\nFrom: 	${memoDsl.fromText}\n${memoDsl.body}\n"
		def sectionStrings =""
		for (s in memoDsl.sections) {
			sectionStrings += s.title.toUpperCase() + "\n" + s.body + "\n"
		}
		template += sectionStrings
		println template
	}
}

A sample program in our newly developed OODSL would be:

package com.solutionsfit.dsl.memotemplate

class MemolDslTest extends GroovyTestCase {
	void testDslUsage_outputText() {
		MemoDsl.make {
			to "Nirav Assar"
			from "Barack Obama"
			message "How are things? We are doing well. Take care"
			text
		}
	}
}

References

<references/>