Sequel gem increment - ruby

I am trying to use the Ruby Sequel gem for DB operations.
I am stuck for incrementing and decrementing values.
The doc says that this should work, even though it seems very strange for me to be able to add a number and a symbol.
2.0.0-p247 :019 > require 'sequel'
=> true
2.0.0-p247 :020 > s = Sequel.connect('sqlite://db.sqlite')
=> #<Sequel::SQLite::Database: "sqlite://db.sqlite">
2.0.0-p247 :021 > s[:query_volume].update_sql(:queries => 3)
=> "UPDATE `query_volume` SET `queries` = 3"
2.0.0-p247 :022 > s[:query_volume].update_sql(:queries => :queries + 3)
NoMethodError: undefined method `+' for :queries:Symbol
from (irb):21
from /Users/avandra/.rvm/rubies/ruby-2.0.0-p247/bin/irb:16:in `<main>'
But as you can see it gives undefined method on the queries symbol. Which is kindof concurs with why it was strange for me.
I tried using curly braces, but that gives another error:
2.0.0-p247 :023 > s[:query_volume].update_sql{:queries => :queries + 3}
SyntaxError: (irb):23: syntax error, unexpected =>, expecting '}'
s[:query_volume].update_sql{:queries => :queries + 3}
^
from /Users/avandra/.rvm/rubies/ruby-2.0.0-p247/bin/irb:16:in `<main>'
And using
2.0.0-p247 :033 > s[:query_volume].update_sql{queries = queries + 3}
=> "UPDATE `query_volume` SET "
just gives a badly formatted SQL...
Could anyone shed some light on how this can be done?

You should use Sequel.expr for that:
s[:query_volume].update_sql(:queries => Sequel.expr(3) + :queries)

Related

what is [-1, 1] in this ruby code?

I am looking at an example of code and confused.
def self.type(input)
input.strip!
return 'question' if input[-1,1] == '?'
end
So, input[-1] makes sense, it is checking if the last character is a question mark. What does the 1 do? Also, all the example tests pass without the 1.
input[-1,1] means reading 1 character from the last character. It gives the same result as input[-1] because you are reading just 1 character from the last character.
Look at some examples to understand more:
❯ irb
2.3.0 :001 > input = 'lenin'
=> "lenin"
2.3.0 :002 > input[-1]
=> "n"
2.3.0 :003 > input[-1,1]
=> "n"
2.3.0 :004 > input[-2]
=> "i"
2.3.0 :005 > input[-2, 1]
=> "i"
2.3.0 :006 > input[-2, 2]
=> "in"
2.3.0 :007 > input[-2, 3]
=> "in"

How can I dynamcially use a parameter as an operator in Ruby?

I want to either add or subtract
so I pass in 'action' as a paramater
How do I do a 'action' b for a+b or a-b
I tried eval but no luck, undefined method 'action'
Use send.
action = "+"
a.send(action, b)
Eval works for me.
2.0.0p247 :006 > action = '+'
=> "+"
2.0.0p247 :007 > eval("5 #{action} 2")
=> 7

Encoding and decoding ruby symbols

I discovered this behavior of multi_json ruby gem:
2.1.0 :001 > require 'multi_json'
=> true
2.1.0 :002 > sym = :symbol
=> :symbol
2.1.0 :003 > sym.class
=> Symbol
2.1.0 :004 > res = MultiJson.load MultiJson.dump(sym)
=> "symbol"
2.1.0 :005 > res.class
=> String
Is this an appropriate way to store ruby symbols? Does JSON provide some way to distinguish :symbol from "string"?
Nope is the simple answer. Most of the time it only really matters for hashes and there's a cheat on hashes, symbolize_keys!. Bottom line is that JSON does not understand symbols, just strings.
Since you are using MultiJson, you can also ask MultiJson to do this for you...
MultiJson.load('{"abc":"def"}', :symbolize_keys => true)

Prepared Statements Already Exists

I am trying to use the prepared statements in ruby with pg gem. This is how my statement looks like
conn.prepare("insert_values", "insert into " + objectName + "(" + headerStr + ") values (" + prep_values + ")")
conn.exec_prepared("insert_values", arr)
I keep getting the error
Prepared Statement insert_values already exists.
How Do i Fix this?? Thanks
Try to run:
conn.exec("DEALLOCATE name_of_prepared_statement")
In your example:
conn.exec("DEALLOCATE insert_values")
Simple test and it is working in my irb:
1.8.7 :001 > require 'rubygems'
=> true
1.8.7 :002 > require 'pg'
=> true
1.8.7 :003 > conn = PGconn.connect(:host => 'localhost', :port => 5912, :user => 'test', :dbname => 'test' )
=> #<PGconn:0x7fe6ac703970>
1.8.7 :005 > conn.prepare("insert_values", "select * from data where id < $1")
=> #<PGresult:0x7fe6ac6b2e58>
1.8.7 :006 > conn.prepare("insert_values", "select * from data where id < $1 and id > $2")
PGError: ERROR: prepared statement "insert_values" already exists
from (irb):6:in 'prepare'
from (irb):6
1.8.7 :007 > conn.prepare("insert_values", "select * from data where id < $1")
PGError: ERROR: prepared statement "insert_values" already exists
from (irb):7:in 'prepare'
from (irb):7
1.8.7 :008 > conn.exec("DEALLOCATE insert_values")
=> #<PGresult:0x7fe6ac6738c0>
1.8.7 :009 > conn.prepare("insert_values", "select * from data where id < $1")
=> #<PGresult:0x7fe6ac665fe0>
1.8.7 :010 > conn.exec_prepared("insert_values",[200])
=> #<PGresult:0x7fe6ac65d188>
1.8.7 :011 > conn.exec("DEALLOCATE insert_values")
=> #<PGresult:0x7fe6ac654df8>
1.8.7 :012 > conn.exec_prepared("insert_values",[200])
PGError: ERROR: prepared statement "insert_values" does not exist
from (irb):12:in 'exec_prepared'
from (irb):12
This is a better way reusing prepare(), avoid prepared statement "my_statement" already exists:
sql = "select * from my_table where id = $1"
begin
ActiveRecord::Base.connection.raw_connection.prepare('my_statement', sql)
rescue PG::DuplicatePstatement => e
end
pg_result = ActiveRecord::Base.connection.raw_connection.exec_prepared('my_statement', [my_table_id])

How are named capture groups used in RE2 regexps?

On this page http://swtch.com/~rsc/regexp/regexp3.html it says that RE2 supports named expressions.
RE2 supports Python-style named captures (?P<name>expr), but not the
alternate syntaxes (?<name>expr) and (?'name'expr) used by .NET and
Perl.
ruby-1.9.2-p180 :003 > r = RE2::Regexp.compile("(?P<foo>.+) bla")
#=> #<RE2::Regexp /(?P<foo>.+) bla/>
ruby-1.9.2-p180 :006 > r = r.match("lalal bla")
#=> #<RE2::MatchData "lalal bla" 1:"lalal">
ruby-1.9.2-p180 :009 > r[1] #=> "lalal"
ruby-1.9.2-p180 :010 > r[:foo]
TypeError: can't convert Symbol into Integer
ruby-1.9.2-p180 :011 > r["foo"]
TypeError: can't convert String into Integer
But I'm not able to access the match with the name, so it seems like a useless implementation. Am I missing something?
Looking at your code output, it seems that you are using the Ruby re2 gem which I maintain.
As of the latest release (0.2.0), the gem does not support the underlying C++ re2 library's named capturing groups. The error you are seeing is due to the fact that any non-integer argument passed to MatchData#[] will simply be forwarded onto the default Array#[]. You can confirm this in an irb session like so:
irb(main):001:0> a = [1, 2, 3]
=> [1, 2, 3]
irb(main):002:0> a["bob"]
TypeError: can't convert String into Integer
from (irb):2:in `[]'
from (irb):2
from /Users/mudge/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
irb(main):003:0> a[:bob]
TypeError: can't convert Symbol into Integer
from (irb):3:in `[]'
from (irb):3
from /Users/mudge/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
I will endeavour to add the ability to reference captures by name as soon as possible and update this answer once a release has been made.
Update: I just released version 0.3.0 which now supports named groups like so:
irb(main):001:0> r = RE2::Regexp.compile("(?P<foo>.+) bla")
=> #<RE2::Regexp /(?P<foo>.+) bla/>
irb(main):002:0> r = r.match("lalal bla")
=> #<RE2::MatchData "lalal bla" 1:"lalal">
irb(main):003:0> r[1]
=> "lalal"
irb(main):004:0> r[:foo]
=> "lalal"
irb(main):005:0> r["foo"]
=> "lalal"

Resources