<    March 2010    >
Su Mo Tu We Th Fr Sa
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
01:36 thomaz joined
04:15 neaf joined
05:15 pietia joined
06:16 dimday joined
06:22 merboutpost joined
06:30 josh0x0 joined
07:21 s_dana joined
07:39 j_dana joined
08:04 Swimming_Bird joined
08:22 mwlang joined
08:24 <mwlang> jeremyevans: I need to fix that select_limit_sql issue that came along with 3.9 that breaks the TOP N on MSDE 2000. Its impacting more code than I anticipated.
08:25 <mwlang> I'll be happy to do the patch and run the specs, but I'm not quite sure where to start with doing detection of the DBMS to determine its pre-2005
08:27 quirkey joined
08:38 <jeremyevans> mwlang: You can use the server_version method to do the detection
08:38 <jeremyevans> mwlang: I think < 9000000 is pre-2005, but I'm not sure
08:39 <mwlang> ok, I'll do a little research.
08:39 <mwlang> I've found the version info for Reporting Services, but not yet for DBMS. The 2000 documentation is long gone from MSDN
08:43 <mwlang> http://support.microsoft.com/kb/321185
08:43 <Mathetes> [00URL] How to identify your SQL Server version and edition
08:45 <mwlang> odd....select serverproperty('productversion') returns a :untitled => nil
08:45 <mwlang> but select @@version does return the info embedded in a long string of info.
08:48 <jeremyevans> mwlang: You can use the server_version *method* to do the detection
08:48 <jeremyevans> mwlang: i.e. DB.server_version
08:49 <mwlang> ah-ha.
09:15 brianmario joined
09:20 <mwlang> hmmm...would a desired approach be to create a sub-adaptor called mssql2000 and have it house the select_limit_sql method? (I'm assuming we don't want to do a server_version test every execute of select_limit_sql)
09:25 <jeremyevans> mwlang: Actually, the test on every execute of select_limit_sql is the correct way to handle it
09:26 <jeremyevans> mwlang: It's not as expensive as you think.
09:26 <mwlang> jeremyevans: ok, then that's how I'll implement it.
09:32 neaf joined
10:47 keithcascio joined
10:59 brianmario joined
11:06 dkubb joined
11:29 neaf joined
12:04 s_dana joined
12:05 j_dana joined
12:05 neaf joined
12:45 dkubb joined
13:39 neaf joined
14:33 IceD^ joined
14:33 <IceD^> heya
14:34 <IceD^> I have model with `type` field for which I want custom accessors (it'll accept MyType instances and convert them into db representation, MyType is custom non-db class)
14:34 <IceD^> how to do this?
14:34 <IceD^> I assume, I can write def type and def type=
14:34 <IceD^> but how to access real field from these methods?
14:35 <bougyman> i would rename that field right now.
14:35 <bougyman> not because you have to, but because of fewer headaches.
14:36 <IceD^> means - have _type in db and simply use type and type= accessors?
14:36 <IceD^> dirty...
14:36 <bougyman> yeah, i wouldn't do that.
14:36 <bougyman> i'd name it something more descriptive and use it in both places.
14:36 <IceD^> don't understand
14:36 <bougyman> you shouldn't need accessors if it's a model, sequel already has accessors for the db fields.
14:37 <IceD^> let me explain
14:37 <spox> IceD^: are they custom types?
14:37 <IceD^> there is AccountType class which is loaded from yaml file
14:37 <IceD^> I don't want and don't need to keep it in db
14:37 <IceD^> it has uuid field which is used to identify account type
14:38 <IceD^> for Account model I have type field in db which will store uuid
14:38 <bougyman> ok.
14:38 <bougyman> i'd name that field uuid
14:38 <IceD^> and I'd like to get real type when using account.type
14:38 <bougyman> and have the 'type' method in your model look up the uuid field and match it in your YAML lookup list.
14:38 kevwil joined
14:38 <IceD^> and - I'd like to prevent users from accessing that uuid directly
14:38 <IceD^> they only need type
14:39 <IceD^> but... I can live with them accessible, I think
14:48 <IceD^> and while I'm here
14:48 <IceD^> what's preffered way for accessing fields
14:48 <IceD^> model.field or model[:field]?
14:50 <IceD^> ouch
14:50 <IceD^> http://pastebin.ca/1842828
14:51 <IceD^> any ideas?
14:53 <IceD^> ahh
14:53 <IceD^> it's necessary to use self.type_uuid in the accessors
15:07 pedrobelo joined
15:33 dimday joined
15:34 <IceD^> /home/iced/dev/wimm/model/account.rb:5: undefined method `validates' for Account:Class (NoMethodError)
15:34 <IceD^> trying to do model validation as in http://sequel.rubyforge.org/rdoc/files/README.html
15:35 <IceD^> ahha - it looks like it's in plugin now
15:41 <IceD^> how do I enable this plugin?
15:44 <dimday> IceD^, try this: http://sequel.rubyforge.org/rdoc-plugins/classes/Sequel/Plugins/ValidationHelpers.html
15:45 <jeremyevans> IceD^: You can call super in the accessors after you do the conversion
15:45 <IceD^> jeremyevans, already solved - I missed self.
15:50 <jeremyevans> IceD^: And model.field is preferrable to model[:field]
15:50 <IceD^> jeremyevans, guessed this as well - as there can be virtual fields e.g.
15:51 <jeremyevans> IceD^: Yep
15:51 <IceD^> btw - sequel is great but documentation really suck
15:52 <IceD^> cheat sheet is great but not enough
15:52 <jeremyevans> IceD^: Patches are welcome :)
15:53 <jeremyevans> IceD^: And the RDoc documentation is fairly good. Introductory documentation is lacking, admittedly.
15:53 <IceD^> yeah
15:53 <IceD^> rdoc is good, but it's damn hard to find smth in it unless you are familiar with sequel already ;)
15:54 <jeremyevans> IceD^: True. The best way to improve the situation is to submit documentation patches
15:54 <IceD^> heh he
15:54 <IceD^> writing docs isn't my favorite thing :)
15:54 <jeremyevans> IceD^: Is there a particular area you are having a problem with?
15:55 <IceD^> nope
15:55 <IceD^> I decided to test sequel while writing my home accounting util (gnucash is killing me with it `usability`)
15:56 <IceD^> and so far I'm doing good
15:56 <IceD^> but that's my 15 years of programming experience
15:56 <jeremyevans> IceD^: That's good. If you think that there's a particular area that we should cover more in the documentation, please let me know
15:56 <IceD^> average coder will get lost in sequel
15:57 <IceD^> it's necessary to add smth like activerecord intro docs
15:57 <IceD^> common use cases
15:57 <IceD^> or - expand cheat sheet with more information about models
15:57 <IceD^> non-model issues are described pretty good here
15:57 <jeremyevans> IceD^: I suppose we have different ideas of the average coder, but the documentation certainly assumes a familarity with both ruby and SQL
15:58 <IceD^> sure :)
15:58 <IceD^> but common person who simply want models (like activerecord, yes) - he will get lost, definitelly
15:59 <IceD^> some small howto with master/detail models, virtual fields, validation will be great to have
15:59 <jeremyevans> IceD^: I don't think it's definite, but I'm sure it can happen to a significant number of people
16:02 <IceD^> and suggestion to feature - if field value is subclass of, let's say, Sequel::VirtualField (or has .from_value and .to_value methods) - it should work transparantly
16:02 <IceD^> I'm always missing this feature in all orms, I used
16:03 <jeremyevans> IceD^: Can you be more specific?
16:03 <keithcascio> Would someone please remind me of the canonical name of the idiom: select || (insert && select) ?
16:03 <jeremyevans> IceD^: Are you saying the setter methods should always check if the passed object has .to_value?
16:04 <jeremyevans> keithcascio: find_or_create
16:04 <IceD^> jeremyevans, not necessary - probably smth like virtual_field :field
16:04 josh0x0 joined
16:04 <jeremyevans> IceD^: I'm still not sure how you would want that to be used. Could you give an example?
16:05 <IceD^> already given about an hour ago, but:
16:05 <IceD^> Account model with type field
16:05 <jeremyevans> IceD^: This it? http://pastebin.ca/1842828
16:06 <IceD^> in application we are using non-model AccountType class which can be mapped to type field and provides some additional info
16:06 <IceD^> yup
16:06 <IceD^> like one_to_one, but not in the db scope
16:06 <jeremyevans> IceD^: Note that the composition plugin supports that, but it was added after 3.9.0
16:07 <IceD^> sequel (3.9.0)
16:07 <IceD^> heh he
16:07 <jeremyevans> IceD^: You need the master branch from github
16:07 <IceD^> when >3.9.0 will be released?
16:07 <jeremyevans> IceD^: Early next month. Generally releases are done in the first week of the month
16:08 <jeremyevans> IceD^: Assuming there are enough changes to warrant a release
16:08 <IceD^> nice ;) I can wait :)
16:09 <keithcascio> What is the most idiomatic way to do FindOrCreate using Sequel?
16:10 <keithcascio> I tried this:
16:10 <keithcascio> def find_or_create(model, *args)
16:10 <keithcascio> (model[*args] || ((model.insert(*args)) && model[*args])).id
16:10 <keithcascio> end
16:11 <jeremyevans> keithcascio: Model.find_or_create already exists. The FindOrCreate association extension is an example of a custom extension.
16:12 <jeremyevans> keithcascio: http://sequel.rubyforge.org/rdoc/classes/Sequel/Model/ClassMethods.html#M000241
16:12 <Mathetes> [00URL] Module: Sequel::Model::ClassMethods [Sequel: The Database Toolkit for Ruby]
16:15 <keithcascio> Thank you Jeremy, that is exactly what I was looking for
16:21 <keithcascio> jeremy: as far as you know, does find_or_create() work well with the :caching plugin? so far I'm seeing more SELECTs in the log than I expect
16:22 <jeremyevans> keithcascio: No. The caching plugin only caches Model.[], and find_or_create uses Model.find()
16:22 <jeremyevans> keithcascio: The caching plugin caches only by primary key, and find is called with an arbitrary hash
16:29 <keithcascio> jeremy: that makes sense. It makes sense for the :caching to cache only by primary key, and it makes sense that find(), and thus find_and_create(), accepts an arbitrary hash
16:30 <IceD^> hmm
16:30 <IceD^> I want to create decimal column in db
16:30 <jeremyevans> IceD^: OK
16:30 <IceD^> e.g. decimal(10,2)
16:30 <jeremyevans> IceD^: OK
16:30 <IceD^> how do I specify this in equel::Schema::Generator.column
16:31 <IceD^> hrrr
16:31 <IceD^> should go to sleep - it's specified in :size desciption
16:31 <jeremyevans> decimal :column_name, :size=>[10,2]
16:32 <IceD^> yeah
16:41 <keithcascio> jeremy: the following works as I want:
16:41 <keithcascio> def lookup_or_create(model, *args)
16:41 <keithcascio> (model[args] || model.create(args)).id
16:41 <keithcascio> end
16:41 <keithcascio> I think
16:42 <keithcascio> no it does not work
16:42 chuck joined
16:48 <jeremyevans> keithcascio: It still won't use caching. Model.[] is only cached is given a primary key
16:48 <jeremyevans> keithcascio: If you give it a hash, it won't cache
16:49 <keithcascio> jeremy: right, I was giving it an array, so it was caching, but then model.create() failed
16:49 <keithcascio> v2:
16:49 <keithcascio> def lookup_or_create(model, *args)
16:49 <keithcascio> (model[args] || model.create(model.primary_key_hash(args))).id
16:49 <keithcascio> end
16:49 <jeremyevans> keithcascio: Composite primary key I assume?
16:49 <keithcascio> yes
16:50 <jeremyevans> keithcascio: That will probably work
16:50 <keithcascio> jeremyevans: I think it will, but right now I'm getting a exception, but I think I understand why
16:51 <jeremyevans> keithcascio: You probably want the *args in the primary key hash
16:51 <keithcascio> jeremyevans: it's the exception thrown on line 933 in base.rb: "method xxxxx= doesn't exist or access is restricted to it" (Sequel::Error)
16:52 <keithcascio> jeremyevans: because I didn't define any accessors in my model subclass
16:52 <keithcascio> jeremyevans: I apologize for how new I am to this, and I appreciate your help
16:53 <jeremyevans> keithcascio: Use Model.unrestrict_primary_key
16:53 <jeremyevans> keithcascio: Primary key access is restricted by default in the mass assignment methods
16:53 <jeremyevans> keithcascio: The default is to assume surrogate keys instead of natural
16:55 <keithcascio> jeremyevans: nice, that worked
16:55 <keithcascio> jeremyevans: yes, for the purposes of my application, I'm using natural keys
16:56 <keithcascio> jeremyevans: the Postgres primary key for each table is actually a surrogate "id" serial
16:56 <keithcascio> jeremyevans: so when I define the model subclasses, I have to set_primary_key() explicitly
16:57 <keithcascio> jeremyevans: so the following is working for me:
16:57 <keithcascio> class Job < Sequel::Model(:job); set_primary_key [:policy, :schedule]; unrestrict_primary_key end
16:57 <jeremyevans> keithcascio: If the database primary key is a surrogate, why do you want to define your own natural?
16:58 <jeremyevans> keithcascio: I can't think of a good reason to do that
16:58 <keithcascio> jeremyevans: for the purposes of this particular app, the lookups are always going to be over the natural key, never the primary key
16:58 <keithcascio> jeremyevans: I'm thinking of the app as a "schema translation", I assume quite typical
16:59 <keithcascio> jeremyevans: it takes a text stream as input, which is a representation of another proprietary "schema", and populates a relational database with that data
16:59 <jeremyevans> keithcascio: Even if the lookups just use the natural keys, you shouldn't set the Sequel primary key different from the database primary key
17:00 <keithcascio> jeremyevans: so every time my app encounters an "object" it must lookup a "handle" to it in the destination database
17:00 <keithcascio> jeremyevans: I thought you might say that about "Sequel primary key different from the database primary key"
17:00 <jeremyevans> keithcascio: I think I understand, but I still think you shouldn't use a different primary key
17:01 <keithcascio> jeremyevans: thank you for your advice
17:01 <jeremyevans> keithcascio: What problem does that solve?
17:01 <keithcascio> jeremyevans: I agree that concepts are important and should not be subverted
17:01 <jeremyevans> keithcascio: I'm trying to understand your reasoning for making the primary key different from the databases'
17:01 <keithcascio> jeremyevans: OK I will explain more
17:02 <keithcascio> jeremyevans: let's say I'm talking about one iteration of the main loop of my program, which looks at a single line of input
17:02 <jeremyevans> keithcascio: OK
17:03 <keithcascio> jeremyevans: that line contains enough "natural" information to lookup records for several "objects" from several different database tables, but of course lacks the surrogate primary keys
17:04 <jeremyevans> keithcascio: Which is fine, you can still lookup by something that is not a key
17:04 <keithcascio> jeremyevans: I need to look up the surrogate key for each "object", and I want caching to work
17:04 <jeremyevans> keithcascio: Ah. So you are trying to use the caching plugin, which only caches based on primary key, by telling Sequel your primary key is different
17:05 <keithcascio> jeremyevans: yes
17:05 <jeremyevans> keithcascio: Not the approach I would recommend, but the reason now makes sense :)
17:05 <jeremyevans> keithcascio: Personally, I'd not use the caching plugin, and just handle caching manually
17:06 <keithcascio> jeremyevans: OK, I assume what I'm doing is abusive of the concepts involved, which I would prefer to avoid
17:06 <jeremyevans> keithcascio: The caching plugin isn't really magical, you should just look at the source code to see what it is doing, and replicate the important parts in your app
17:07 <keithcascio> jeremyevans: this app just seems so typical, I felt that a database toolkit should support what I'm doing
17:07 <jeremyevans> keithcascio: It's possible something as simple as checking a populating a hash should work
17:07 <keithcascio> jeremyevans: yes, a simple hash suffices
17:08 <keithcascio> jeremyevans: and it would be simple to implement
17:08 <jeremyevans> keithcascio: Well, apparently Sequel does, but I haven't encountered your use case before :)
17:08 <keithcascio> jeremyevans: this has gotta be a very common use case
17:08 <keithcascio> jeremyevans: you've got some huge "legacy" app that doesn't expose any kind of typical relational API
17:09 <keithcascio> jeremyevans: you're only access to it's data is through command-line programs that dump out enormous amounts of semi-structured text
17:10 <keithcascio> jeremyevans: you want to put all that in a modern, structured relational schema
17:10 <keithcascio> jeremyevans: it's a "schema translation"
17:10 <keithcascio> jeremyevans: the source "database" probably keeps its own primary keys, but you have no access to them
17:10 <jeremyevans> keithcascio: What your describing probably isn't that rare, but the details are different enough that a ready made tool doesn't already exist
17:11 <keithcascio> jeremyevans: interesting
17:11 <jeremyevans> keithcascio: Adding your own cache via a hash is probably about 2 lines of code, and it's what I would always do
17:11 <jeremyevans> keithcascio: I wouldn't have even thought to use models or plugins
17:11 <keithcascio> jeremyevans: this is an interesting conversation for me, thank you
17:12 <jeremyevans> keithcascio: Since this is a strict procedural import, I'd have stuck with basic datasets
17:12 <keithcascio> jeremyevans: I appreciate that perspective
17:13 <keithcascio> jeremyevans: this isn't the first time I've had to write a schema translation like this
17:13 <keithcascio> jeremyevans: I did it at my former place of employment as well
17:14 <jeremyevans> keithcascio: I've done some similar things, but usually they've been small enough that it was fairly easy to just write the script manually
17:14 <keithcascio> jeremyevans: it's been a common use case in my life
17:14 <keithcascio> jeremyevans: I believe in the principle that a programmer should struggle not to write code
17:15 <keithcascio> jeremyevans: I believe in idiom
17:15 <jeremyevans> keithcascio: Sequel would make it fairly easy to write a library that took an import format, and export schema, and a mapping, and handling importing into a database
17:15 <jeremyevans> keithcascio: But that's not something that Sequel handles all by itself, and I'm not aware of another library like Sequel that handles it either
17:16 <keithcascio> jeremyevans: from what I've gathered, Sequel is the state of the art, so I wouldn't expect much out of another toolkit
17:17 <jeremyevans> keithcascio: I certainly feel it's the most advanced ruby database library :)
17:18 <jeremyevans> keithcascio: If I found myself doing the same type of import over and over, I'd certainly write the library to make it simpler
17:21 <keithcascio> jeremyevans: the library you describe -- great idea
17:22 <jeremyevans> keithcascio: If it's something you are interested in working on, I'd be happy to answer any questions you have regarding Sequel
17:23 <keithcascio> jeremyevans: I haven't committed myself to a particular style of solution just yet
17:24 <keithcascio> jeremyevans: I've written so much code in my life, and I've seen programmers in a rush to write code, I'm not quite so desperate
17:25 <keithcascio> jeremyevans: when I approach a task, the first thing I want to educate myself about is: what concepts have been developed by others who care about this arena?
17:26 <jeremyevans> keithcascio: A wise approach.
17:26 <keithcascio> jeremyevans: that's what relational database theory is, after all
17:26 <keithcascio> jeremyevans: it's people who've been racking their brains for decades, asking themselves: "what are the important use cases?"
17:27 <keithcascio> jeremyevans: "how can we build a powerful system that automates the things that seem to come up frequently?"
17:27 <keithcascio> jeremyevans: it's the essence of declarative programming itself
17:27 <keithcascio> jeremyevans: thank you, btw
17:28 <jeremyevans> keithcascio: I agree. And thank you for the interesting discussion :)
17:28 <keithcascio> jeremyevans: the practice of programming is relatively young
17:29 <keithcascio> jeremyevans: smart people try to introduce technology/concepts that streamline the work: e.g. RDMS theory, functional programming theory
17:29 <keithcascio> jeremyevans: but there is surprising resistance to these styles
17:30 <keithcascio> jeremyevans: people just want to learn how to write a for(;;) loop and write that same for(;;) loop over and over
17:30 <keithcascio> jeremyevans: but that's not the future
17:32 <keithcascio> jeremyevans: the future is more declarative, "logical"
17:38 greg8si joined
17:38 <keithcascio> jeremyevans: I am at the point where I finally understand the sense in which SQL is a logical programming language: you give the RDBMS a theorem and it finds a proof of that theorem -- beautiful
17:40 <keithcascio> jeremyevans: designers had to figure out "how do we _say_ such and such?" and "how do we _compute_ such and such is the most general possible case?"
17:41 <keithcascio> jeremyevans: "in the most general possible case?
17:42 <jeremyevans> keithcascio: Sorry, got pulled away
17:42 <jeremyevans> keithcascio: The beauty of SQL is that it is declarative and doesn't require internal knowledge from the user
17:43 <jeremyevans> keithcascio: The downside is that you can't generally control how the database gets the information
17:43 <jeremyevans> keithcascio: But most decent databases have good optimizers, and do a better job than most users would be able to do
17:44 <keithcascio> jeremyevans: for sure
17:44 <keithcascio> jeremyevans: another beauty is just to learn the concepts that appear in modern databases
17:45 <keithcascio> jeremyevans: it's been a way for me to clarify my thinking
17:46 <keithcascio> jeremyevans: I might have imagined doing something another way, resisted the RDBMS way, but ultimately realized the established way was far more elegant and general
17:46 <keithcascio> jeremyevans: of course, as you note, there are limitations
18:04 merboutpost joined
20:31 quirkey joined
21:38 brianmario joined
21:45 dkubb joined
22:30 quirkey joined
23:41 bdimcheff joined