Tuesday, September 15, 2015

First Meeting with Postgres

I had to uninstall Postgres as I forgot the password for default admin user "postgres". What stupid I am. It really makes things difficult. So I have to uninstall the postgres. OK, another bad thing I made is I installed postgres by EnterpriseDB installer. It's always not an easy way to uninstall stuff that was not installed by homebrew. Fortunately, I found the following way to uninstall the postgres:
http://stackoverflow.com/questions/8037729/completely-uninstall-postgresql-9-0-4-from-mac-osx-lion

After the uninstallation, I installed postgres by homebrew:
$brew update
$brew install postgres

OK, now I've installed postgres successfully. It's time to lauch the postgres server by:
$pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start
and check it is running:

$ps aux | grep postgres

Everything works as expected, and I tried to run rails but got an error:
FATAL:  role "dashboard" does not exist

It seems that I don't have that role created in postgres. Not a problem, it's easy to create a role by:
$createuser -P dashboard
Log into postgres and check the role:
$psql -d postgres -U [login user name]
postgres=# SELECT rolname FROM pg_roles;
       rolname       
---------------------
... 
dashboard

Good! The role "dashboard" has been created successfully. Now try rails again. What? another error again?
PG::InsufficientPrivilege: ERROR:  permission denied to create database
Looks like the role "dashboard" doesn't have the permission to create database. Check the permission for "dashboard" in postgres:
postgres=# \du
                                 List of roles
     Role name      |                   Attributes                   | Member of
---------------------+------------------------------------------------+----------
dashboard |                                                | {}

Yeah, no permission at all for "dashboard". Grant it appropriate permission:
postgres=# ALTER ROLE dashboard CREATEROLE CREATEDB;

Now, run the rails again. Sigh...another error again:
"dashboard_development" does not exist
I see. It's most likely because I didn't do db:create and db:migrate. So, let me do it:
$bundle exec rake db:create db:migrate

Well, finally the website is up and running!

Sunday, July 5, 2015

Memory Configuration on STM32F407

1. Stack Overflow

The process maintains its stack and the stack size is configured as following:
1:   ;*******************************************************************************   
2:   ; Amount of memory (in bytes) allocated for Stack   
3:   ; Tailor this value to your application needs   
4:   ; <h> Stack Configuration   
5:   ; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>   
6:   ; </h>   
7:   Stack_Size  EQU  0x00008000   
8:       AREA STACK, NOINIT, READWRITE, ALIGN=3   
9:   Stack_Mem  SPACE Stack_Size   
10:   __initial_sp   
11:  </code></pre>  
So the code above defines the default stack size as 0x8000 (32Kb). If you have a buffer larger than 32Kb or you have a very deep recursive call, the stack will overflow. Once the overflow happens, the processor will generate an interrupt and jump to the interrupt handler which is HardFault_Handler.
I created a very simple test code shown as below to verify this behavior.
1:  #define BUF_SIZE (32*1024L)
2:  int main( void )  
3:  {  
4:       char buf[BUF_SIZE];  
5:       buf[0] = 'a';  
6:       buf[BUF_SIZE-1] = 'x';  
7:       printf("buf allocated on STACK, buf[%d]=%c, buf[%ld]=%c\r\n",  
8:            0, buf[0], BUF_SIZE, buf[BUF_SIZE-1]);  
9:  }  
If you run this code, nothing will output. If you run the JTAG debugger,  and set a break point in HardFault_Handler, you'll see the code flow reaches the break point.
Note, the reason the printf is not working in HardFault_Handler is the main stack is corrupted.
On the other hand, if you increase the Stack_Size beyond BUF_SIZE or reduce the BUF_SIZE below 32Kb, you'll see the output.

2. STM32F407 on-chip SRAM

By roughly looking at the STM32F407 datasheet, you are aware that you can use up to 192Kb SRAM. And you probably want to allocate the entire SRAM as stack to the processor and thus no heap. So you just increase the Stack_Size to 0x0002ffff and then you compile the code. However, you'll see following errors during the link stage:
1:  assembling startup_stm32f40xx.s...  
2:  linking...  
3:  .\Obj\STM32F407VET.axf: Error: L6406E: No space in execution regions with .ANY selector matching startup_stm32f40xx.o(STACK).  
4:  .\Obj\STM32F407VET.axf: Error: L6407E: Sections of aggregate size 0x30000 bytes could not fit into .ANY selector(s).  
5:  Not enough information to list image symbols.  
6:  Not enough information to list the image map.  
7:  Finished: 2 information, 0 warning and 2 error messages.  
Weird, right? Does it mean that we can't use the entire memory for stack? The answer is "YES we CAN" but we need to do a little bit more configuration. Looking at the STM32F407 datasheet again, you'll realize that the 192Kb SRAM actually consists of two on-chip SRAM, one of which is 128Kb while the other is 64Kb. By default, the Keil project doesn't include the second 64Kb into memory so you have to opt in that chip.
Now, try to compile the code again and you'll see the errors gone!

Wednesday, June 17, 2015

Ruby on Rails 2015-06-16

1. Route the pages.
(1) If you want to be able to route to your new view, open config/routes.rb and add the line

get 'view_name/index'

(2) If you want to set the default page to a certain, open config/routes.rb file, add

root 'store#index', as: 'store'

So the index will be routed to the index of controller store. The as: 'store' tells Rails to create a store_path accessor method.

2. yield method in view/layouts/application.html.erb. This method will render the content of the view that user is currently browsing. For example, if the user is browsing http://localhost/store, then the content of views/store/index.html.erb will be rendered in the yield section. Similarly, if the user is browsing http://localhost/products, then the content of views/products/index.html.erb will be rendered.

3. Did "rake test" but encountered five errors:
(1) AbstractController::Helpers::MissingHelperError: Missing helper file helpers//users/alexsun/documents/rubys/workspace/depot/app/helpers/application_helper.rb_helper.rb

(2) ProductsControllerTest#test_should_show_product:
ActionView::MissingTemplate: Missing template products/show, application/show with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]} 

(3) - (5) similar to (2), all are "Missing template"

I didn't see these error when I was using Ruby 2.2.0. But after that I switched back to Ruby 2.0.0 and then these error appears. I fixed them by changing my workspace name "Depot" to "depot" and all errors are gone. It seems to me a Ruby bug which is in Ruby 2.0.0 but fixed in Ruby 2.2.0.

Monday, June 15, 2015

Ruby on Rails 2015-06-15

Object-Relational Mapping

ORM libraries map database tables to classes. If a database has a table called products, the program will have a class named Product. Rows in the table correspond to objects of the class -- a particular product is represented as an object of class Product.

ActiveRecord is the ORM layer supplied with Rails. It closely follows the standard ORM model: tables map to classes, rows to objects, and columns to object attributes. By relying on convention and starting with sensible defaults, ActiveRecord minimizes the amount of configuration that developers perform.

To understand the ActiveRecord, here is the example:
In models/product.rb, a class Product is define:
class Product < ActiveRecord::Base
end

In db/migrate/xxx_create_products.rb, a class CreateProducts is define:
class CreateProducts < ActiveRecord::Migration
    def change
        create_table:products do |t|
        end
    end
end

By this way, Product has been mapped to the prodcuts table in the database. And the cool thing is that the Product calss that wrap the database table provides a set of class-level methods that perform table-level operations. To understand this, here is the example:
(1) find the product with a particular ID
product = Product.find(1)
(2) collect the objects whos name is 'dave'
product = Product.where(name: 'dave')
You don't need to care about how to manipulate the SQL query to get the data. Rails class wraps them for you and all you need to do is code like OO programming.

Ruby on Rails 2015-05-23

1. Rails provides a simple way to do data validation. The model layer is the gatekeeper between the world of code and the database. If a model checks the data before writing to the database, then the database will be protected from bad data. The source code is in app/models/xxx.rb. An example of validation is:
    validates :title, :description, :image_url, presence: true

2. Rails provides a test framework. The framework is in test directory. You can test the entire framework by:
    $ rake test
Unit test cases can be created in test/models directory, and you can test a particular test case file, e.g.:
    $ rake test:models

3. We use assertion to tell the framework whether our code passes or fails.  The simplest assertion is the method assert(), which expects its argument to be true, e.g.:
    assert product.invalid?, "DEBUG COMMENTS"
    assert product.errors[:title].any?

4. Fixture is a specification of the initial contents of a model under test. Fixture data is specified in the test/fixture directory. The name of the fixture file is significant. The base name of the file must match the name of a database table. The default for the test is to load ll fixtures before running the test, but again you can control which fixtures to load by specifying the following line in the test/models/xxx_test.rb:
    class ProductTest < ActiveSupport::TestCase
      fixtures :products
      ...
    end
The name of the fixture file determines the table that is loaded, so using :products will cause the products.yml fixture file to be used.

5. There are three databases that has been created in the configuration that scaffolding provides.
(1) db/development.sqlite3 will be the development database.
(2) db/test.sqlite3 is a test database.
(3) db/production.sqlite3 is the production database.
rake test command automatically gets a freshly initialized table in the test.sqlite3 database loaded from the fixtures we provide. Also we can do it separately by running rake db:test:prepare.

Thursday, May 21, 2015

Ruby on Rails Note - 05/20/2015

1. css files are in app/asset/stylesheets/xxx.scss. Rails keeps application.html.erb as a framework page for the entire application. The application.html.erb file is located in views/layouts/ directory. In order to use the xxx.scss, it has to be introduced in the application.html.erb file, in such way as following.
  <body class='xxx.scss'> or <body class='<%= controller.controller_name%>'>
Then, the css classes can be used in index.html.erb.

2. Some rails helper function:
(1) cycle('a', 'b') sets the css class of each row to either 'a' or 'b' and automatically toggles between the two style names on successive lines.
(2) trunctate(string, length:n) is used to display just the first n characters of string.
(3) strip_tags(string) removes the html tags from the string.
(4) link_to('Product', @product) is equal to
     link_to('Product', controller:'products', action:'show', id:product)
     The link_to generates  a hyper link which execute show method in controller which invokes show.html.erb if nothing in the method.

3. Git usage
(1) basic configuration
    $ git config --global --add user.name "Alex"
    $ git config --global --add user.email alex@gmail.com
    $ git config --global --list
These configuration info will be added every check in as the committer info.
(2) add a .gitignore file to specify a file list that you don't want to check in
(3) create a local empty repository in current directory.
    $ git init
(4) add all the files under the current directory to local repository.
    $ git add .
(5) commit the change to local repository
    $ git commit -m "first commit"

If you want to clear the local repository.
(1) rm -rf .git

If you have a github account, you can push your repository to the github
(1) create a repository on github
(2) $ git remote add origin "YOUR HTTPS GITHUB REPOSITORY URL"
(3) $ git push origin master




Tuesday, May 19, 2015

Ruby on Rails Note - 05/19/2015

1. To create a new project.
    $ rails new [project name]

2. Create a scaffold. A scaffold is a full set of model, database migration for that model, controller to manipulate it, view to view and manipulate the data, and a test suite for each of the above.
    $ rails generate scaffold Product \
            title:string description:text image_url:string price:decimal

The default database for Rails development is SQLite3. The config/database.yml file tells Rails where to look for the database.

3. To migrate database.
    $ rake db:migrate

The migration file is xxxxxxxxxxxxxx_create_xxxx.rb. A migration represents a change we want to make to the data, expressed in a source file in database-independent terms. These changes can update both the database schema and the data in the database tables.

4. To start rails server.
    $rails server

5. To import seed data to the database.
    $rails db:seed

The data can be defined in db/seed.rb.

Monday, April 20, 2015

Start Ruby on Rails!

Installing Ruby on Rails on Mac OS X Yosemite

1. Install latest Xcoder (6.3)

2. Install Command Line Tools which is premise for step 6:
    Xcoder -> Open Developer Tool -> More Developer Tools...

3. Install RVM:
    $ curl -L https://get.rvm.io | bash -s stable

4. Install latest ruby (2.2.1):
    $ rvm install 2.2.1 --autolibs=enable

5. Configure the environment to be ruby 2.2.1:
    $ rvm use 2.2.1

6. Install latest rails (4.2.1)
    $ gem install rails --version 4.2.1 (--no-ri --no-rdoc)

7. Make ruby 2.2.1 as the default environment
    $ rvm --default 2.2.1

After installation, there might be something that you would like to do, such as upgrade to newer version.
1. To find out all the versions of Rails that you have installed:
    $ gem list --local rails

Installing PostgreSQL on Mac OS X Yosemite
1. www.postgresql.org/download/macosx/  find a installer on the website and install PostgreSQL.
2. Install the database driver for PostgreSQL. Driver can be downloaded from https://bitbucket.org/ged/ruby-pg/wiki/Home. You have to specify the pg_config location. PostgreSQL installed by EnterpriseDB keeps pg_config in /Library/PostgreSQL/9.4/bin/pg_config
$gem install pg -- --with-pg-config=/Library/PostgreSQL/9.4/bin/pg_config

To be continued:
1. Version Control (Git) ?
2. Continuous integration (CI) system?
3. Editors?