Comments (30)
Hey sorry for a late reply - ROM doesn't support relationship DSL but it does support joining relations. I will come up with some examples that will (hopefully) work so you should be able to judge yourself if it's good enough for you.
from rom.
No big rush, I tried using ROM with the axiom-memory-adapter and emulating ActiveRecord::Base.first_or_create!
by using ROM::Relation#restrict
in a spec and 6 examples took 71 seconds, so I'm not going with ROM for now and just manually optimizing searches with hashes, etc.
It appeared that doing the check for collisions with restrict
was adding 60 seconds on top of just creating the rows. Here's the code I was using. If I'm doing something incredibly stupid please let me know as I'd much prefer to be able to use ROM and an AREL-like syntax than have to manually do the in-memory search when the user doesn't have a database and I can't use AREL.
BITS_PER_BYTE = 8
RANDOM_ID_BYTES = 16
RANDOM_ID_BITS = RANDOM_ID_BYTES * BITS_PER_BYTE
RANDOM_ID_N = 2 ** RANDOM_ID_BITS
#
# Methods
#
# An environment for in-memory models.
#
# @return [ROM::Environment] environment with schema and mapping already
# declared
def self.environment
environment = ROM::Environment.setup(
memory: 'memory://metasploit-framework'
)
environment.schema do
base_relation :architectures do
repository :memory
attribute :id, Integer
attribute :abbreviation, String
attribute :bits, Integer
attribute :endianness, String
attribute :family, String
attribute :summary, String
key :id
end
end
environment.mapping do
architectures do
map :id,
:abbreviation,
:bits,
:endianness,
:family,
:summary
model Metasploit::Framework::Architecture
end
end
seed(environment)
environment
end
# Generates a random ID with the same number of bits as
# `SecureRandom.uuid`
#
# @return [Integer]
# @see SecureRandom.random_number
def self.random_id
SecureRandom.random_number(RANDOM_ID_N)
end
def self.seed(environment)
ROM::Session.start(environment) do |session|
Metasploit::Model::Architecture::SEED_ATTRIBUTES.each_with_index do |attributes, i|
relation = session[:architectures].restrict(attributes)
if relation.count == 0
seed = Metasploit::Framework::Architecture.new(attributes)
seed.id = random_id
seed.valid!
# XXX not sure why I need to manually call track since the
# rom-rb.org shows me just using save.
session[:architectures].track(seed)
session[:architectures].save(seed)
end
end
session.flush
end
end
from rom.
Oh wow that's great feedback thank you for this. I will take a closer look and get back to you asap.
from rom.
while somewhat offtopic your can create an inmemory sqlite database: https://gist.github.com/schmurfy/6378497
from rom.
If you are on *nix you can create the sqlite db on the /tmp folder, since
it is RAM based.
Em 29/08/2013 11:05, "Julien Ammous" [email protected] escreveu:
while somewhat offtopic your can create an inmemory sqlite database:
https://gist.github.com/schmurfy/6378497—
Reply to this email directly or view it on GitHubhttps://github.com//issues/3#issuecomment-23491614
.
from rom.
metasploit-framework used sqlite in the past, but metasploit-framework is threaded and sqlite kept having issues, so I was advised that it wasn't worth using sqlite @schmurfy. Additionally, the full schema from metasploit_data_models using postgres only features like INET columns.
metasploit-framework needs to run on Windows and *nix-like systems (Linux and OSX mostly), so I can't depend on that behavior @mereghost.
from rom.
@solnic I wanted to make sure you noticed, but I had to make two non-obvious changes from the examples on rom-rb.org:
- I had to call
session[:archtectures].track(seed)
before I could callsession[:architectures].save(seed)
. - I had to use
session.flush
instead ofsession.commit
.
from rom.
Yeah that's my bad. I will fix the examples. Thanks for pointing this out.
On Thu, Aug 29, 2013 at 4:24 PM, Luke Imhoff [email protected]
wrote:
@solnic I wanted to make sure you noticed, but I had to make two non-obvious changes from the examples on rom-rb.org:
- I had to call
session[:archtectures].track(seed)
before I could callsession[:architectures].save(seed)
.2) I had to use
session.flush
instead ofsession.commit
.Reply to this email directly or view it on GitHub:
#3 (comment)
from rom.
@limhoff-r7 I updated the example.
You can use a short-cut syntax to create new object and track it automatically via session[:architectures].new(seed)
.
How many objects do you have in that seed btw?
from rom.
@limhoff-r7 can you see if it gets a bit faster when doing environment[:architectures].restrict(seed).count
instead of using session?
The difference is that session sets up IdentityMap and state tracking and "plain" environment does not. You might get a perf boost. We also don't have an optimised #count
yet so at the moment it loads all the objects matching criteria.
Is this code publicly available? I could try it out locally and see how I could improve stuff :)
from rom.
@limhoff-r7 oh and btw how many objects do you have there?
from rom.
16 objects when I did the test.
from rom.
I wouldn't have used count
if there was an exists?
or exist?
method.
from rom.
@limhoff-r7 ugh 16 objects? that's very weird. I need to try to reproduce this, something is wrong. I was expecting you'd say 16k objects or something heh
from rom.
I pushed up a branch with the specs running slow here: https://github.com/limhoff-r7/metasploit-framework/tree/feature/rom (so the feature/rom branch of my fork of metasploit-framework).
git clone [email protected]:limhoff-r7/metasploit-framework.git
cd metasploit-framework
git checkout feature/rom
rspec spec/app/models/metasploit/framework/memory_spec.rb
The specs as a whole will fail since this branch was cut off of feature/module-caching, which is under going major rework, so only run this one spec.
from rom.
If you're not using an IDE like Rubymine that allows you to click-through to definition, it may not be obvious what the seed attributes actually are, so here's a direct link to them in metasploit-model: https://github.com/rapid7/metasploit-model/blob/feature/module-caching/lib/metasploit/model/architecture.rb#L51
from rom.
@limhoff-r7 thank you! I'll investigate during the weekend
from rom.
@snusnu do you think it makes sense to show how you can set up joined relations? it would be pretty verbose and people might be confused by it (maybe?). wdyt?
from rom.
@solnic yes i think that makes sense, and i don't think that it's pretty verbose by the way. Imo we shouldn't only think of this as a relationship replacement, but as demonstrating a way to map SQL views (with the added benefit of being writable under a lot of circumstances). Furthermore, I have the feeling that apps developed with ROM will typically involve some mappings of this kind. I think that quite a few places will emerge, were modeling a specific set of data is more naturally expressed by means of (mapping) a view , than by (building new objects around) relationships.
from rom.
@snusnu I wholeheartedly agree there’s only one caveat right now - mappers don’t support loading data from a joined relation
from rom.
@solnic oh heh, i forgot. Do EVs work already, or is it just ECs that don't work atm?
from rom.
@snusnu you'd have to build your own mapper, there's no EV/EC concept in rom-mapper yet but we could probably easily add it
from rom.
@solnic then i guess we should show an EV example with a simple custom mapper. For EC, i guess we'd either postpone it until group/ungroup
lands in axiom
at which point it will be trivial for rom-mapper
. Or we try to come up with some intermediate solution that knows how to hand a set of flat tuples to a mapper instance for consumption. I'd hate to do that fwiw, and that's also the reason why I made a case for having group/ungroup
support in axiom
sooner rather than later. It's imo even more important than SQL write support, as i've said before.
from rom.
@solnic our recent design change, resulting in mapper only ever seeing one tuple, makes group/ungroup even more important.
from rom.
@solnic fwiw, that doesn't mean i'm against providing something that can be used in ROM::Relation#each
and "collapses" the n flat tuples into one grouped tuple, sending that to mapper.load
. But I'm afraid that we will need quite some infrastructure for that to work out reasonably well (and I haven't yet thought about write support). We'd need FK information in order to perform group
properly ourselves. Unless I'm missing something, of course.
from rom.
@solnic I'm afraid that hand rolling group/ungroup
in rom-relation, will add tons of completely superfluous complexity, given that it will be replaced by something really trivial eventually. I'm totally not sure if that's worth it.
from rom.
Who’s talking about group/group? :) I’m talking about mapping a bunch of attributes into an embedded object.
from rom.
@solnic yeah, no problem for EV. but how to do EC without group/ungroup?
from rom.
@solnic let's continue this in IRC (needn't be now)
from rom.
FYI, Axiom::Relation
now supports #group,
#ungroup, #wrap and
#unwrap`. This should open up EC and EV support in ROM once the following is added:
ROM::Relation#group
ROM::Relation#ungroup
ROM::Relation#wrap
ROM::Relation#unwrap
from rom.
Related Issues (20)
- Being able to initialise a fully populated ROM::Struct HOT 24
- AutoStruct does not respect type definition when creating HOT 9
- Relation with name `:schema' causes registration problems
- Relax freezing policy for `ROM::Configurable`
- Using Repository#transaction with non-default gateways HOT 2
- Fix Ruby 3.0 compatibility HOT 3
- Running tests raises 'Too many open files - getcwd (Errno::EMFILE)' HOT 1
- Inconsistency between Time formats in ROM::Changeset::PipeRegistry and ROM::Plugins::Command::Timestamps HOT 1
- Relation doesn't work in repository HOT 2
- delete: :by_pk in a repository breaks with timestamps plugin
- Associated entities are not mapped to their entity-classes in case of alias HOT 3
- Error when a relation with the name `options` exists. HOT 2
- Unable to modify the node of a combined assc. when a child of that assc. is combined.
- Aggregate write on self referencing relation not setting foreign key HOT 1
- Batch insert with one INSERT query HOT 7
- Fix multiple association block use to prevent ROM::AssociationSet registry error HOT 1
- Rails 7.1 incompatibility (Object#with) HOT 5
- Broken example code, unexpected auto_struct behavior HOT 3
- uninitialized constant ROM::Memory::Types::Int HOT 3
- Rails 7.1 Upgrade Causes map_with To Throw ArgumentError HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rom.