From ae4cafdfbeb95a2427530e9910a26ddc8f31819b Mon Sep 17 00:00:00 2001 From: colinnewell Date: Wed, 24 Feb 2016 21:20:25 +0000 Subject: [PATCH 1/3] Update Cookbook.pod Updated documentation to refer to recommended quote_names rather than quote_char and name_sep. --- lib/DBIx/Class/Manual/Cookbook.pod | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index ce68fc24b..a55d6abe9 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -1692,20 +1692,11 @@ customers as above. If the database contains column names with spaces and/or reserved words, they need to be quoted in the SQL queries. This is done using: - $schema->storage->sql_maker->quote_char([ qw/[ ]/] ); - $schema->storage->sql_maker->name_sep('.'); + $schema->storage->sql_maker->quote_names(1); -The first sets the quote characters. Either a pair of matching -brackets, or a C<"> or C<'>: +This will automatically determine which quotes are required for your RDBMS. - $schema->storage->sql_maker->quote_char('"'); - -Check the documentation of your database for the correct quote -characters to use. C needs to be set to allow the SQL -generator to put the quotes the correct place, and defaults to -C<.> if not supplied. - -In most cases you should set these as part of the arguments passed to +In most cases you should set this as part of the arguments passed to L: my $schema = My::Schema->connect( @@ -1713,8 +1704,7 @@ L: 'db_user', 'db_password', { - quote_char => '"', - name_sep => '.' + quote_names => 1, } ) @@ -1724,8 +1714,7 @@ this, you can also overload the C method for your schema class: sub connection { my $self = shift; my $rv = $self->next::method( @_ ); - $rv->storage->sql_maker->quote_char([ qw/[ ]/ ]); - $rv->storage->sql_maker->name_sep('.'); + $rv->storage->sql_maker->quote_names(1); return $rv; } From 5b9431f2275b49cef36516df5e28bb813afb019b Mon Sep 17 00:00:00 2001 From: Colin Newell Date: Wed, 24 Feb 2016 22:51:45 +0000 Subject: [PATCH 2/3] Reworked the quoting advice --- lib/DBIx/Class/Manual/Cookbook.pod | 58 +++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index a55d6abe9..e1d0691d9 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -1690,13 +1690,12 @@ customers as above. =head2 Setting quoting for the generated SQL If the database contains column names with spaces and/or reserved words, they -need to be quoted in the SQL queries. This is done using: - - $schema->storage->sql_maker->quote_names(1); +need to be quoted in the SQL queries. This is done by passing in the +C attribute into the connect_info when connecting a schema. This will automatically determine which quotes are required for your RDBMS. -In most cases you should set this as part of the arguments passed to +This is generally done like this with, L: my $schema = My::Schema->connect( @@ -1708,15 +1707,50 @@ L: } ) -In some cases, quoting will be required for all users of a schema. To enforce -this, you can also overload the C method for your schema class: +Turning quoting on is generally a good idea, and there is even a helper +to allow you to do it without requiring explicit configuration. - sub connection { - my $self = shift; - my $rv = $self->next::method( @_ ); - $rv->storage->sql_maker->quote_names(1); - return $rv; - } +See L. + +Turning quoting on does mean that all terms assumed to be identifiers will +be quoted. This means that you need to be careful with complex expressions +used on the left hand side where identifiers are assumed. A query like this +would work without quoting on. + + return $self->search(undef, { + '+columns' => [ + { items => 'sum(items.quantity)', + ] + }); + +With it on the whole chunk would get encoded and so you would end up with +an error complaining that the field C<"sum(items.quantity)"> does not exist. + +There are several ways to resolve this, often there is a data structure that +SQL Abstract can interpret into the function call, in this case +C<< { sum => 'items.quantity' } >> is equivalent. + +Here are some examples, including using literal SQL by passing in a string +reference. + + return $self->search(undef, { + join => ['items'], + '+columns' => [ + { items => { sum => 'items.quantity', -as => 'items' }}, + { lines => { count => 'items.quantity', -as => 'lines' }}, + { total => \'sum(items.quantity*items.per_item*(1+items.vat)) as total' }, + ], + }); + +If you need to provide variables where there is an identifier take a look at the +L. + +Also note that the opposite is possible too. If you need to use an identier on +the right side you can use the construct C<< { -ident => 'column' } >> + +For example, + + return $self->search({ col1 => { -ident => 'col2' }}); =head2 Working with PostgreSQL array types From 2b694bcf0d380bd54d58d6e935d1216ee087d4cf Mon Sep 17 00:00:00 2001 From: Colin Newell Date: Mon, 19 Dec 2016 17:54:09 +0000 Subject: [PATCH 3/3] Added reference back to quote_char and name_sep. --- lib/DBIx/Class/Manual/Cookbook.pod | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index e1d0691d9..0eba7278a 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -1694,6 +1694,8 @@ need to be quoted in the SQL queries. This is done by passing in the C attribute into the connect_info when connecting a schema. This will automatically determine which quotes are required for your RDBMS. +This is sugar for the C and C properties and should +set them correctly for your RDBMS. This is generally done like this with, L: