Why can't we use :key => value in CodeIgniter's DB library? - mysql

I've used to use something like this with the regular PHP's PDO:
$data = array(
":name" => "james",
":location" => "Palo Alto, CA"
);
SQL:
SELECT * FROM people WHERE name LIKE :name and location = :location
When i've started to use Codeigniter, it won't let me use namespace keys anymore, it only accepts the traditional ? marks.
Anyway to fix that?

Unfortunately, no, there isn't. Not with CodeIgniter natively.
It helps to remember that CodeIgniter's roots are in PHP4 compliant code (and some of the things they did are not even the most recent PHP 4 -- they use a custom file searching system which is substantially slower than glob which was around by PHP 4.3 (4.4? It was around for the minimum required version), this means that the old '?' was really the best option at the time.
If you feel better about using the newer style, then you might be better off using the PDO classes. They're better and faster anyway. (Frankly, I only use CI's DB classes for compliance. I have a very strong preference for PDO's, especially since all of the modern frameworks seem to use them). I will warn you, though, that the use of PDO's completely invalidates the ActiveRecord framework offered by CodeIgniter. You will not be able to use $this->db->select()->from('table')->where($array)->limit(1,4); More importantly, you will need to know the differences between the different dialects of SQL, something CodeIgniter lets you avoid (and your code won't be DB agnostic anymore).

Maybe you will be more comfortable using Active Record in Codeigniter and doing something like
$this->db->like();
Look here: http://codeigniter.com/user_guide/database/active_record.html

Related

Which way is better in optimal terms for use Active Record query

Actually I am working in a WebSite that uses MySql DataBase and I want to know which of these two forms is better to make:
Using the object to create others queries:
#inform=Dailyinform.where(:scheduled_start => (##datestart..##dateend)).order("scheduled_start DESC").searchServer(##serverSearch).searchDomain(##domain_name)
#dailyInforms=#inform.where.not(:status => 'COMPLETED').searchFailed.page(params[:page]).per_page(5000)
#restarts=#inform.searchRelaunched.order("scheduled_start DESC").page(params[:page]).per_page(5000)
or Directly with the ActiveRecord Model - Base:
#dailyInforms=Dailyinform.where.not(:status => 'COMPLETED').where(:scheduled_start => (##datestart..##dateend)).order("scheduled_start DESC").searchFailed(##serverSearch).page(params[:page]).per_page(5000)
#restarts=Dailyinform.where(:scheduled_start => (##datestart..##dateend)).order("scheduled_start DESC").search2(##serverSearch).page(params[:page]).per_page(5000)
My question arose because i felt that the second way is faster that the first way. Maybe is just my impression! Thanks
When it comes to performance I don't think there will be any difference. Active record is good at being lazy when it comes to making queries, it won't perform any until you actually try to use the result.
For this reason I would say that the first method is preferable since it is more DRY.

Perl DBI without accessing the database

I'm creating a set of SQL INSERT statements for a database that doesn't exist yet, and I'm saving them to file.
How can I use Perl's powerful DBI module to create those INSERT statements without accessing a specific database. In particular, it looks like using the $dbh->quote() function requires that I instantiate $dbh with a connection to a database.
Unfortunately, the actual quote() behaviour isn't always a portable characteristic, so each driver will do them differently. Unless you connect to a driver, you don't know which quoting format to use in practice. (There is one module that might do this without a connection, DBIx::Abstract, but it is not especially current.).
The quote() method is actually implemented by the corresponding driver class, in the DBD::* namespace. You might attempt to load the driver you need and call the function directly (see http://search.cpan.org/~timb/DBI-1.616/lib/DBI/DBD.pm#Writing_DBD::Driver::db::quote) but this feels grubby.
I'd still make a DBI connection, if only so that you get the right format of quoting. You don't need to actually send it any statements, but then you do know that the quoting format will be correct for the database you will use.
From DBI::quote:
For most database types, at least those that conform to SQL standards, quote would return 'Don''t' (including the outer quotation marks). For others it may return something like 'Don\'t'
That is, the behavior of DBI::quote varies from database to database, and it doesn't make sense to call it in a database-independent way.
Make a trivial connection to a database of the same type you are writing for, or learn your database's quoting conventions and implement a quote method yourself. See the DBI source for a reference implementation.
Usually you would use DBI by specifying a database like so:
my $dbh = DBI->connect("DBI:mysql:database=$db_name;host=127.0.0.1");
However, your database does not yet exist so you cannot connect to it. You can use DBI without specifying a database like so:
my $dbh = DBI->connect("DBI:mysql:;host=127.0.0.1");
You could use DBD::CSV or DBD::AnyData as a dummy database. SQLite is good for this purpose, too.
A hidden advantage of using SQLite here is that it's a semi-real database, and will tend to make you write code in a way that's decoupled from any specific database.
According to perl -MDBI -E 'say join(q{,},DBI->available_drivers);'
in clean Debian chroot with only DBI (package "libdbi-perl") installed the following drivers are available right away:
DBM,ExampleP,File,Gofer,Proxy,Sponge
The minimum DBI connect statement that works for me is
my $dbh=DBI->connect("DBI:DRIVER:"); # DRIVER is one of [DBM,File,ExampleP,Sponge,mysql,SQLite]
That is enough to use $dbh->quote() with no database whatsoever.
DBM and File escape q{'} as q{\'} ("mysql" style);
ExampleP and Sponge escape: q{'} as q{''} ("SQLite" style).
You can also use:
DBD::_::db->quote()
To access the quote function without setting up a database handle. I don't believe it is specific to MySQL though.

Fetching strategy encapsulation for Entity Framework 4.1 and NHibernate

I created a project to test out NHibernate 3+ vs. Entity Framework 4.1, wrapping it in a repository, making it very testable using interfaces etc.
I do not want to expose either ORM outside of the repositories (I do not even expose IQueryables). Everything should be handled in that layer and until I tried to handle fetching in an abstract way, everything was good.
Microsoft's implementation of adding eager loading uses either magic strings (yuck) or Linq expressions (yay) on the Include function. Their syntax follows something like this:
IQueryableThing.Include(o => o.Person);
IQueryableThing.Include(o => o.Company.Contact);
IQueryableThing.Include(o => o.Orders.Select(p => p.LineItem.Cost);
The first will just load the associated person. (parent)
The second will load the associated company and each company's contact. (parent and grandparent).
The third will load all associated orders, line items and costs for each order.
It's a pretty slick implementation.
NHibernate uses a slightly different approach. They still use Linq expressions, but they make heavier use of extension methods (fluent approach).
IQueryableThing.Fetch(o => o.Person);
IQueryableThing.Fetch(o => o.Company).ThenFetch(o => o.Contact);
IQueryableThing.FetchMany(o => o.Orders).ThenFetch(p => p.LineItem).ThenFetch(q => q.Cost);
(I'm not sure I if the third line is the correct syntax)
I can encapsulate a list of expressions in a separate class and then apply those expression to the IQueryable within that class. So what I would need to do is standardize on the Microsoft expression syntax and then translate that into NHibernate's syntax by walking the expression tree and rebuilding each expression.
This is the part that's really tricky. I have to maintain a particular order of operations in order to call the correct function for the IQueryable (must start with either Fetch or FetchMany, with each subsequent being a "ThenFetch" or "ThenFetchMany"), which stops me from using the built-in ExpressionVisitor class.
Edit:
I finally created an expression parser that will take any level of nesting of properties, collections, and selects on collections and produce an array of expressions. Unfortunately, the built in Fetch extensions methods do not take LambdaExpression as a parameter.
The part I am stuck on currently is not being able to use the built in Fetch definitions from nHibernate. It looks like I may have to hit the Remotion library's functions directly or register my own extension methods that will satisfy their parser.
Funky.
Have you tried using NHiberanteUtil.Initialize()? I haven't attempted to do what you are doing, but I think Initialize will work akin to Include().

Can we change the way Rails writes HTML IDs and such?

I just started checking out Wordpress' CSS Architecture to study a system that's established and pretty powerful to learn better HTML habits. I've noticed they use all hyphens - (post-554 for example), while Rails uses underscores _ (post_554 for example). I'm wondering if there's some setting to customize this in Rails, something like ActionView::Template.word_boundary = "-".
Is there? Not that it really matters, just trying to learn why people do things the way they do.
:)
You can't change se separator. It is hard-coded into Rails.
For example, post_554 is generated by the dom_id helper, which internally relies on the RecordIdentifier class.
Here's the definition.
def dom_id(record, prefix = nil)
if record_id = record.id
"#{dom_class(record, prefix)}#{JOIN}#{record_id}"
else
dom_class(record, prefix || NEW)
end
end
The separator, the JOIN constant, is defined as freezed String so you can't change it.
module RecordIdentifier
extend self
JOIN = '_'.freeze
NEW = 'new'.freeze
There are two ways to change it:
Create your own helper (suggested)
Overwrite the existing methods/helpers with your own implementations (not suggested)
There are also some technical restrictions that explain the reason behind this choice, mainly tied to the language behind Rails.
For instance, talking about symbols
:post_554 # valid symbol
:post-554 # invalid symbol
:"post-554" # valid symbol
Using - would probably require a less cleaner approach to Ruby.
Personally, I prefer using - rather than _ and I tend to avoid standard Rails helpers unless strictly required.

What's a good syntax for an HTML link markdown to make internal links easier?

I want to create a good syntax for making it easier to link to internal things, kind of like a Wiki, so maybe I'm thinking the user can use something like:
Bah bah bah reference: [[a]]
And it would convert it into HTML:
Bah bah bah reference: title
but I'm worry about interjection and security issues. What's a good syntax to pick (maybe [[]] or something else) and what's a safe regex for it?
Don't reinvent the wheel: Text::Markdown.
While Sinan's idea of using an existing syntax, such as Markdown, is a good one, the viability of this sort of approach depends on the particulars of your situation. You haven't told us enough to get very helpful responses. Are you starting from a blank slate or are you inheriting a large body of existing documents that would require a costly conversion process, not to mention staff retraining?
If the latter, sometimes it's best to tackle the problem by thinking in terms of short-term workarounds and long-term strategies. The short-term workaround -- some sort of home-grown syntax precisely like that proposed in your question -- will be ugly and may cause hassles here and there, but it can get the job done. For example, our organization has a large pile of Word documents that ultimately provide content for HTML pages. Within those Word files, staff member use an approach like this to create links and make a few other declarations that our parsing code handles: ##some_link##. There are many ways for this to fail, but in the type of content that we are producing, it rarely occurs. Partly for that reason, it's difficult to generate much enthusiasm for a long-term strategy of migrating the content to a more robust system. My expectation is that such a migration will occur, but it is being driven by larger considerations and not by the limitations of our kludgy ##foo## markup device.
Update:
Based on your additional comments, it sounds like you will have a list of links that you want your users to be able to add quickly, using short IDs. So, those links will be defined someplace, say a Perl hash. You can use this hash to guard against invalid entries. For example:
use strict;
use warnings;
my %approved_links = (
so_perl => 'http://stackoverflow.com/questions/tagged/perl',
so_ruby => 'http://stackoverflow.com/questions/tagged/ruby',
);
my $regex = qr/ \[\[ ([^\]]+) \]\] /x;
while (<DATA>){
die "Danger: $_\n" if map {
exists $approved_links{$_} ? () : ($_)
} /$regex/g;
s/$regex/$approved_links{$1}/g; # Not complete, but you get the idea.
print;
}
__DATA__
Some text [not an id] [[so_perl]] more [[so_ruby]] more..
[[so_perl]] blah [[so_ruby]] blah
[[bad id!!]]
Something like Textile or Creole? Why don't you use an existing implementation?