design question : variadic functions use ? .
-
(probably a TOmato vs toMAto kind of questions... ) At what point should I use variadic functions vs. keeping it local ? I have a library that handles SQL queries. is there a difference between something like : (overly simplified)
// do the formatting before calling the function.
std::string fullyFormedQuery = sprintf (queryFormat, param1, param2, ... );
void DoRequest( std::string fullyFormedQuery){
// call SQL with the fullyFormedQuery
}// do the formatting in the function.
void DoRequest( std::string queryFormat, param1, param2, ... ){
std::string fullyFormedQuery= queryFormat(format, param1, param2, ... );
// call SQL ...
}CI/CD = Continuous Impediment/Continuous Despair
-
(probably a TOmato vs toMAto kind of questions... ) At what point should I use variadic functions vs. keeping it local ? I have a library that handles SQL queries. is there a difference between something like : (overly simplified)
// do the formatting before calling the function.
std::string fullyFormedQuery = sprintf (queryFormat, param1, param2, ... );
void DoRequest( std::string fullyFormedQuery){
// call SQL with the fullyFormedQuery
}// do the formatting in the function.
void DoRequest( std::string queryFormat, param1, param2, ... ){
std::string fullyFormedQuery= queryFormat(format, param1, param2, ... );
// call SQL ...
}CI/CD = Continuous Impediment/Continuous Despair
As you say it's more of a style question. My preference would be for the first option (pass fully formed string) because: - there is less documenting to do - some compilers (MSVC for one), check matching between format strings and parameters in (s)printf functions but don't do that in a user defined variadic function.
Mircea
-
As you say it's more of a style question. My preference would be for the first option (pass fully formed string) because: - there is less documenting to do - some compilers (MSVC for one), check matching between format strings and parameters in (s)printf functions but don't do that in a user defined variadic function.
Mircea
thanks.
CI/CD = Continuous Impediment/Continuous Despair
-
(probably a TOmato vs toMAto kind of questions... ) At what point should I use variadic functions vs. keeping it local ? I have a library that handles SQL queries. is there a difference between something like : (overly simplified)
// do the formatting before calling the function.
std::string fullyFormedQuery = sprintf (queryFormat, param1, param2, ... );
void DoRequest( std::string fullyFormedQuery){
// call SQL with the fullyFormedQuery
}// do the formatting in the function.
void DoRequest( std::string queryFormat, param1, param2, ... ){
std::string fullyFormedQuery= queryFormat(format, param1, param2, ... );
// call SQL ...
}CI/CD = Continuous Impediment/Continuous Despair
Just noting that your examples leave out using bind variables. My understanding, and I just googled to see if that seems to be correct, is that bind variables make optimizations in the database easier. Not to mention of course that they are a better fit for avoiding SQL injection problems. Setting up bind variables is rather complex so putting it in the method is going to be better.
-
Just noting that your examples leave out using bind variables. My understanding, and I just googled to see if that seems to be correct, is that bind variables make optimizations in the database easier. Not to mention of course that they are a better fit for avoiding SQL injection problems. Setting up bind variables is rather complex so putting it in the method is going to be better.
Thanks. :thumbsup: We already have a complete (decades old) framework for SQL. (seems to be working fine) maybe I should have left out the SQL reference and make it a more generic question.
CI/CD = Continuous Impediment/Continuous Despair
-
Thanks. :thumbsup: We already have a complete (decades old) framework for SQL. (seems to be working fine) maybe I should have left out the SQL reference and make it a more generic question.
CI/CD = Continuous Impediment/Continuous Despair
Maximilien wrote:
complete (decades old) framework for SQL.
Then you should use the same idiom as the existing code. Changing it for some and not others just adds to the confusion. Although if a preference for one is given and there is a large amount of new work (new files not modifying existing code) then maybe go with there.
-
Maximilien wrote:
complete (decades old) framework for SQL.
Then you should use the same idiom as the existing code. Changing it for some and not others just adds to the confusion. Although if a preference for one is given and there is a large amount of new work (new files not modifying existing code) then maybe go with there.
I will not change existing code; it's just too dangerous. I'm just curious; if there's a best practice.
CI/CD = Continuous Impediment/Continuous Despair
-
I will not change existing code; it's just too dangerous. I'm just curious; if there's a best practice.
CI/CD = Continuous Impediment/Continuous Despair
My best practice doesn't fit either of your suggestions... If I am creating a new database layer (which I have numerous times) then the caller would never provide the SQL. If the business layer(s) need new database logic then the database layer should be modified to provide it. The caller provides the parameters that would be used in the call. Then within that database layer method it would decide how to process the parameters and SQL (provided by the method.) So it looks like the following.
void DatabaseDoX(param1, param2,...)
{
// multiple variations possible
std::string fullyFormedQuery = sprintf (SQL_X, param1, param2, ... );There are quite a few variations on the above. For example consider the complication of a user initiated call where they might specify different 'query' terms (like data range, customer name, etc) But all still hide the SQL. Certainly there are design considerations for example your code might be coming from within the database layer (not a business call at all.) If so then I suspect that usage would actually vary depending on what the database layer was specifically doing in the code path.