receive all matching networks for IP address from postgres db - ruby-on-rails

I have a postgres db with a table networks which includes a column network of type cidr. I want to queue all networks which contain an IP address I provide. I couldnt find how to do this.
Currently I pull all networks, and then use the include? method IPAddr class provides:
Network.all.each{|row| pp row if row.network.include?("10.176.0.5")}

You can use postgres' >>= operator (includes or equal) or >>(includes) that is defined for cidr type:
Network.where(['network >> ?', "10.176.0.5"])

Related

InfluxDB where query on tag values

I am trying to write a where clause on InfluxDB where the points are filtered via their key values.
My points have the field ping_to_google.com and the tag key user where user can be raspi-2 or raspi-5. This is a sample output of the database:
> select * from networks where time > now()-1h
name: networks
time ping_to_google.com user
---- ------------------ ----
1645494054000000000 3.528 raspi-2
1645494078000000000 3.578 raspi-2
I am using InfluxDB version 1.8 and InfluxDB shell version 1.6.4
This query will work!
select * from networks where time > now()-1h AND "user"='raspi-2'
According to the documentation of the influxDB you should only single qoute tag values:
Tags
tag_key <operator> ['tag_value']
Single quote tag values in the WHERE clause. Queries with unquoted tag values or double quoted tag values will not return any data and, in most cases, will not return an error.
They don't specify how to write tag keys. It is crazy that the database does not produce any errors in most cases. Also, it's not clear (and very unexpected after reading this documentation) that the tag key should be double-qouted. But this works and is how to do it!

Query for records with an IPaddress NOT contanied within a CIDR column

I have two existing Tables:
Devices has a column inet: ipaddress
Networks has a column inet: cidr
I need a scope on the Devices table which returns only those devices which have an ipaddress that is NOT contained in any of the networks.cidr
NOTE: postgres has an INET operator << to check if a CIDR contains an ipaddress. But that only handles a single CIDR while I have a whole table of them.
I need something like this:
class Device
scope :not_in_any_network, -> where("devices.ipaddress NOT IN (?)", Network.select(:cidr))
The goal is to be able to chain the scope with others like:
problems = Device.active.not_in_any_network.other_scopes
I was able to get the results I wanted using the following code:
Device.where('devices.ipaddress <<= ANY(ARRAY[?]::inet[])', Network.pluck('TEXT(cidr)'))
Casting the Network.cidr to TEXT was required to avoid the error "TypeError: can't quote IPAddr".
Then I had to cast the array to inet[] so the << operator would work.

Neo4j rb finding connectivity between 2 nodes

I am using neo4j.rb in my rails application.
I already have two nodes n1 and n2 retrieved from the database.
Now i need to check if they have a path between them, i was thinking of using cypher queries using Neo4j::Session.query
But since i already have the two nodes i do not want to retrieve them again inside the query,(does it affect performance?) is there a way to do it?
I know i can use query1 = n1.query_as(:node1) and use it as the node identifier but how can i introduce n2 within the same query object so that i can check connectivity between them.
I want something equivalent to the query
RETURN
CASE
WHEN node1-[*..6]-node2
THEN 'Connected within 6 nodes'
ELSE 'Not connected within 6'
END
Where i already have node1 and node2.
Is a way to do this and also can this be done without using the CYPHER DSL?
Here you go!
n1.query_as(:n1).match_nodes(n2: n2).match('n1-[*1..6]-n2').count
If you want to avoid the Cypher DSL I think you can do that with associations. As a starter example to traverse one level of relationships you can do this:
class N1Class
include Neo4j::ActiveNode
has_many :out, :test_association, type: :TEST_ASSOCIATION, model_class: :N2Class
end
n1.test_association.include?(n2)
That will test if they are directly connected via the test_association association. You can even specify false for your type to ignore the direction and false for the model_class to ignore the target labels.
To get the variable length you can do this:
n1.test_association(nil, nil, rel_length: 1..6).include?(n2)

Evaluating similar strings

Person has many addresses. I'm trying to create an address for a person if the JSON response from an API is different from any of the addresses in the db.
I wrote the following, which works with literal use cases; it prevents duplicate addresses:
p = Person.find(1)
unless p.addresses.any? { |i| i.address_1.eql?(#response['addresses'][0]['street'].upcase) }
This works by taking the array, mapping the address object, and calling eql? on the address_ column (street address).
However, if the street address is suffixed with "blvd" or "ln", I want to add that address to the person. I haven't found a method that evaluates two strings for similarities. Is there some method like similar_to? that might help me?

Quote column name

I have a table containing 2 "uncommon" columns - order and like.
The table are replicated on two databases - MySQL and PostgreSQL.
And i need same app to connect to both databases and use same query on both:
PageModel.where("`like` >= ?", params[:liked])
This will work in MySQL only.
How to make ActiveRecord to quote the column name?
Something like:
PageModel.where("%s >= ?" % quote_column_name(:like), params[:liked])
I found a method that is useless for now - it just returns the column name without quote it.
http://www.rubydoc.info/docs/rails/3.2.8/ActiveRecord/ConnectionAdapters/Quoting:quote_column_name
Perhaps it is just a placeholder and there are another method that does this?
This depends from from one database adapter to the other. So basically, each adapter overrides this method with their own definition.
You're interested in:
ActiveRecord::Base.connection.quote_column_name "my_column"

Resources