SQL DOM: Compile Time Checking of Dynamic SQL Statements

Russell A. McClure and Ingolf H. Krüger University of California, San Diego Department of Computer Science and Engineering 9500 Gilman Drive, La Jolla, CA 92093-0114, USA {rmcclure, ikrueger}@cs.ucsd.edu

1. INTRODUCTION ABSTRACT The term impedance mismatch [17] refers to the inherent Most object oriented applications that involve persistent data disconnect between and programming languages. Many interact with a relational . The most common interaction solutions have been proposed, including language extensions [4, mechanism is a call level interface (CLI) such as ODBC or JDBC. 11, 16], call level interfaces [2, 13, 21], object/relational mapping While there are many advantages to using a CLI – expressive [10, 15, 18] and persistent object systems [3, 7, 20]. power and performance being two of the most key – there are also Call level interfaces offer the full expressive power of SQL by drawbacks. Applications communicate through a CLI by providing an interface that accepts dynamically generated SQL constructing strings that contain SQL statements. These SQL statements, but they provide no static syntax or type checking. statements are only checked for correctness at runtime, tend to be Language extensions, such as SQLJ[4], do provide some static fragile and are vulnerable to SQL injection attacks. To solve these syntax and type checking but they are limited to static SQL and other problems, we present the SQL DOM: a set of classes statements. Object/relational mapping and persistent object that are strongly-typed to a database schema. Instead of string systems allow stored data to be treated as objects but they do not manipulation, these classes are used to generate SQL statements. expose the full power of the database engine. We show how to extract the SQL DOM automatically an existing database schema, demonstrate its applicability to solve In this paper, we focus on overcoming the problems associated the mentioned problems, and evaluate its performance. with accessing relational databases through call level interfaces from object oriented programming languages. Categories and Subject Descriptors D.2.7 [Software Engineering]: Distribution, Maintenance, and 1.1 Problem Definition Enhancement – Restructuring, reverse engineering, and Call level interfaces (CLIs) are powerful because they provide a reengineering. low level interface to the database engine. Interfacing with a database engine through a CLI involves constructing SQL D.2.11 [Software Engineering]: Software Architectures – Data statements through string concatenation and substitution. This abstraction. allows the developer to create very flexible and powerful queries. However, the resulting queries cannot be checked for correctness General Terms until they are sent to the database engine at runtime. Algorithms, Reliability, Security. There are many types of problems and errors that can arise when constructing SQL statements in this way. Some of the more Keywords common problems are bad syntax, misspelled column and table SQL, SQL DOM, Impedance Mismatch, SQL Strings, SQL names and data type mismatches. SQL strings (strings that contain Injection, Dynamic SQL SQL statements) are also very fragile with respect to changes to the database schema. In medium to large sized projects, the number of SQL strings can become quite large. As an application evolves and the database schema changes, it becomes a difficult task to maintain the SQL strings that are in the code base. SQL Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are strings also pose a security risk. They leave an application not made or distributed for profit or commercial advantage and that copies extremely vulnerable to SQL injection attacks [14]; this type of bear this notice and the full citation on the first page. To copy otherwise, attack is typically based on malicious code inserted into a web or republish, to post on servers or to redistribute to lists, requires prior form, and then – as part of the processing of the form – into a specific permission and/or a fee. dynamically generated SQL string. The resulting query leads to ICSE’05, May 15–21, 2005, St. Louis, Missouri, USA. execution of the malicious code, resulting in adding/removing Copyright 2005 ACM 1-58113-963-2/05/0005...$5.00. data from the database.

88

1.2 Solution Proposal Without compiler support the developer can never be sure that the Our goal is to provide a way to have the full expressive power of code and database schema remain consistent. Unit tests, even if dynamic SQL statements, without the inherent problems they exist, are also rarely complete enough to uncover all mentioned in the previous section. The end result is increased deviations between code and schema. Using the SQL DOM maintainability, reliability and security for the application. would eliminate this problem. The compiler would be able to assist in the maintenance process, thereby increasing the Our solution consists of an executable, sqldomgen, which is reliability of the application. Having the SQL DOM, developers executed against a database. The output generated by sqldomgen would be more willing to make changes to the database schema to is a Dynamic Link Library (DLL) containing classes that are meet the needs of their customers. strongly-typed to a database schema. We refer to these classes as the SQL Domain Object Model (SQL DOM). Using these classes, Applications that need to make it to market quickly also stand to the application developer is able to construct dynamic SQL gain from using the SQL DOM. The SQL DOM eliminates all statements without manipulating any strings. syntax and data type mismatch bugs, which can easily slip into applications that use SQL strings. The SQL DOM also frees the Using this method, the compiler is enlisted to eliminate the developer from to perform many unit tests on data access possibility of SQL syntax, misspelling and data type mismatch code. This in turn allows getting the product to market faster. problems. Names of tables and columns are incorporated into the SQL DOM through class names or enumeration members. Data The SQL DOM can also be used to enforce SQL coding types of columns become types of constructor and method standards. For example, you may want to only allow tables to be parameters. Having the compiler catching bugs that used to show joined by a foreign key relationship. Or, only allow filter up only occasionally at runtime increases the reliability of the conditions to be placed on indexed columns. The SQL DOM can application. be tailored to enforce these standards. As the database schema changes throughout the life of an application, the support of the compiler also increases the 2. THE EXISTING METHOD In this section we will demonstrate by example some of the maintainability of the application. If the database schema problems with dynamic SQL strings. In the following section we changes, sqldomgen is rerun, generating a modified SQL DOM. will show how our SQL DOM alleviates these problems. To When the application is then rebuilt with the modified SQL illustrate the existing methods and our proposed solution we will DOM, compiler errors such as the following would be generated: use a simple database with four typical tables as shown in Figure • No such class exists. This would happen if a table or 1. The tables store information about customers, products, orders, column was renamed or removed. and order details. • Data type conversion error. This would happen if the data type of a column was changed. • Missing constructor parameter. This would happen if a new column was added to a table. The security of an application using the SQL DOM is increased because all known SQL injection attacks are eliminated (this currently only applies to our test database engine, SQL Server 2000). In an application that uses SQL strings, defending against SQL injection attacks is very difficult. There is no single place strings are constructed. There is usually no single place through which all database-bound user input passes. The SQL DOM represents a single point of defense. All SQL statements are constructed by the SQL DOM. All database-bound user input passes through constructors of classes in the SQL DOM. These constructors perform the necessary escaping and data type validation to eliminate the threat of SQL injection.

1.3 Applications We believe that any application that is currently using SQL strings could benefit from the SQL DOM. However, there are a few areas we feel would benefit more than others. Figure 1. A sample database schema Applications being developed with the extreme programming A common problem that is introduced by using SQL strings is (XP) methodology tend to evolve rapidly through the misspelled table and column names as shown in Figure 2. The development process. Iterative user feedback results in iterative compiler cannot offer us any aid in catching these kinds of errors. changes to the application and database schema. These changes Code reviews would be of limited help because of the difficulty in can lead to a large amount of time being spent keeping existing manually finding misspelled words. SQL strings consistent with the changing database schema.

89

in their program to hold a column value is of a different type than the column itself. Even 100% statement coverage during testing is not enough to catch a data type mismatch.

Figure 4 contains a function to generate an SQL string to Figure 2. SQL string with misspelled names the UnitsInStock column of the Products table. The SQL data type of the UnitsInStock column is smallint, a 16 bit integer. The Misspellings such as this should be caught during unit testing and developer of the function has mistakenly coded the unitsInStock the example we have shown most likely would be caught at that parameter as an int, a 32 bit integer. The compiler will not time. However, SQL strings are often not that simple, as we will complain about this. This bug will lay dormant until a value that see in the next example. is too large for the smallint to hold is passed into this function. In Figure 3 we see a common example of a function that uses The result will be a runtime error generated by the database string concatenation to dynamically filter the result set of a engine. statement. Conditions are added to the where clause of the select statement for each of the function parameters that the caller specifies. This example also contains a misspelled column name on line 46. In addition, if line 44 is executed, there will be no space between the AND keyword and the column name resulting in an invalid SQL statement. These errors are more difficult to find during unit testing than the errors in the previous example. Calling the function is not enough. Finding these errors depends on particular values being passed in to certain parameters. 100% statement Figure 4. SQL string with a data type mismatch coverage would be required to find these kinds of errors. That may be easy to accomplish with only few tables in the database The maintenance of SQL strings is also problematic. Changes to schema. But if the project contains hundreds of SQL strings to the database schema during the life of an application are check, 100% statement coverage may be prohibitively time guaranteed for any non trivial database application. These consuming. changes can come either during the initial development of an application or as part of the requirements for a new version. When confronting database schema changes, development teams are faced with difficult questions. How much work will it take to modify the existing body of SQL strings to stay in sync with the changing database schema? How much time will the testing effort require to validate that the SQL strings are in sync with the database schema? How many customer support calls will we receive as a result of runtime errors due to invalid SQL strings? SQL strings also render an application highly susceptible to SQL injection attacks [14]. A seemingly harmless function such as the one listed in Figure 5 is a major security hole. A malicious user could craft the value of the companyName parameter in such a way, that they could execute arbitrary SQL statements against the database engine. For example, if the value of companyName was set to “Bad Guy’; drop table Customers --“, the Customers table would be dropped.

Figure 5. A major security hole There is also a lack of developer support during the development Figure 3. SQL string with syntax errors of SQL strings. The IDE cannot prompt developers with a list of table names or column names because as far as it knows, the Another type of error that can occur in SQL strings is a data type developer is writing a string. This means that developers must mismatch. This occurs when a data type that developers are using have the database schema memorized, or they must look up the

90

needed information. Having to look up such detail frequently can 3.3 Concrete Object Model break their concentration. This, in turn, can lead to decreased The object model consists of three main types of classes. They are productivity. As the size of the database increases, this problem is SQL statements, columns and where conditions. exacerbated. Figure 6 shows a few of the SQL statement classes generated for our sample database. For each of the four types of SQL 3. SQL DOM statements (select, , update and ), a class is created for Our solution consists of two parts. The first is an abstract object each table in the database schema. These classes are used to model. The second is an executable, sqldomgen, which is construct SQL statements. To construct a select SQL statement executed against a database schema to generate a concrete for the customers table, you would use an instance of the instantiation of the abstract object model. In this section, we will CustomersTblSelect-SQLStmt class. To construct an update SQL examine our solution in depth. statement for the Orders table, you would use an instance of the OrdersTblUpdateSQLStmt class. Each class is associated with a 3.1 Abstract Object Model single table. The constructors of each class are typed to take only Developing the abstract object model was the most challenging parameters representing columns of the table with which the class problem we faced. We wanted to develop an object model that is associated. accomplished two things which were not entirely orthogonal. Our first goal was to construct an object model that could be used to construct every possible valid SQL statement, which would execute at runtime. Our second goal was for our object model to be easy to use. We felt that if the developer had to go through too many contorted and confusing steps, our tool would not be used, and would therefore be useless. When we were forced to choose between the two goals, we always chose the first goal. One example of the struggle between these two goals occurred during the design of the class that would be used to construct insert SQL statements. For an insert SQL statement to be valid it has to contain a value for every column in the table that is not auto increment or does not have a default value specified. We had two implementation options. The first was to have the constructor take all of the required values as parameters. This would allow the compiler to ensure that all necessary values were supplied to the insert SQL statement. The other option was to have properties or functions that would be used to associate a value for a column Figure 6. SQL statement classes with the insert SQL statement. This would be a little more developer friendly but the compiler would not be able to Select SQL statements have a JoinTo method for guarantee the validity of the insert SQL statement. In line with each table with which they share a foreign key relationship. This goal number one, we chose option one. precludes the developer from having to remember or look up the names of the foreign and primary key columns. 3.2 SQL DOM Generator Column classes, shown in Figure 7, are used as parameters to the We knew that we would need to generate code dynamically for constructors and methods of the SQL statement classes. They are our solution to be viable. The first author was familiar with the used to specify which columns are to be selected, updated or classes in the .NET Framework that allow for the dynamic inserted. Column classes hold data in variables of the same type generation and compilation of code. As a result, sqldomgen was as the column with which it is associated. Since some tables have developed using # [6] and the .NET Framework [1]. Our columns with identical names, namespaces are used to prevent approach, however easily generalizes to other development name collisions. languages and frameworks, including Java. sqldomgen performs three main steps. The first step is to obtain the schema of the database. This is currently accomplished by using methods provided by an OLEDB Provider. The second step is to iterate through the tables and columns contained in the schema and output a number of files containing a strongly-typed instance of the abstract object model. The final step is to compile these source files into a dynamic link library (DLL). To ensure that changes to the database schema result in compile time errors, we envision the sqldomgen being executed as part of the daily build of an application. Figure 7. Column classes

91

It is within the column classes that SQL injection attacks are mitigated. Column classes, whose data type is string, parse and possibly modify the values that are passed to them. For example, a single quote in a string value would be escaped to two single quotes to prevent an SQL injection attack. Other data types besides strings do not require escaping to be performed because of the strongly-typed nature of the classes. A class that represents a column whose data type is int only accepts values that are valid ints. It does not accept string values that could possibly contain an SQL injection attack. In this way the compiler is leveraged to assist us in thwarting such attacks.

Figure 8. Where condition classes Figure 10. GetCustomers using SQL DOM The final type of class that we will look at in the SQL DOM are Figure 11 shows a rewritten SetUnitsInStock function. The old where condition classes. These classes, shown in Figure 8, are version of the SetUnitsInStock function suffered from a hard to used to specify conditions in the where clauses of select, update find data type mismatch bug. If a developer accidentally did the and delete SQL statements. Where condition objects are added to same thing using the SQL DOM, a compiler error message would SQL statements through the AddWhereCondition function. Where be generated like the one shown as a tool tip in Figure 11. condition classes can also be grouped together and arbitrarily sqldomgen generated a UnitsInStock property whose type nested to create complex conditions. matches the type of the UnitsInStock column. Internally, the UnitsInStock property instantiates the UnitsInStockUpdateColumn class to do all of the work. The type 3.4. SQL DOM in Action of the UnitsInStock column is smallint, which is equivalent to a In this section we demonstrate how the SQL DOM overcomes the short in C#. When an int is assigned to the property instead of a problems associated with SQL strings that were described in short, the compiler generates an error. The developer would be Section 2. reminded that the data type of the UnitsInStock column is in fact Figure 9 shows a rewritten GetAllCustomers function. The short and the appropriate code changes could be made. previous version of this function had some misspelled table and column names. In the new version, there are no strings at all. Misspelling a column or table name in the new function would result in a compiler error message.

Figure 11. SetUnitsInStock using SQL DOM Figure 9. GetAllCustomers using SQL DOM Our final function rewrite is shown in Figure 12. The previous Figure 10 shows a rewritten GetCustomers function. The old version of this function was a gaping security hole. The SQL version suffered from an SQL syntax bug as well as some DOM has now plugged the hole. If a malicious user attempts to misspelling problems. In the new version, all of the SQL syntax is perform an SQL injection attack [14] by submitting a specially being generated by the SQL DOM thereby eliminating those crafted value for the companyName parameter, it will be errors. The new version is also much easier to read and mitigated by the CompanyNameUpdateColumn class (created comprehend which tends to result in increased maintainability. internally by the CompanyName property). In the case where the value of the companyName parameter was set to “Bad Guy’; drop table Customers –“, the CompanyNameUpdateColumn would modify it to be “Bad Guy’’; drop table Customers –“. The attack would have failed.

92

The readability of code accessing the database is increased, because class names make explicit use of the “language” created by the database schema; simple syntactic errors, such as string concatenation errors are avoided entirely. This may come at the expense of a slight increase in code length, caused by length of class names in the SQL DOM. While a thorough evaluation in production environments is an element of future work, we have already witnessed these benefits Figure 12. A plugged security hole in a large enterprise integration effort; in this project, quality prototypes have to be produced at high frequency, while The SQL DOM encapsulates the entire database schema. Because concurrent changes to multiple database schemata require of this, the IDE now knows the database schema. Therefore, flexibility in the code accessing the database. The SQL DOM developers can rely on the IDE to prompt them for, say, column provides this flexibility and increases database access security at names, as in Figure 13, or the data type of a column, as in Figure the same time. 14. This relieves developers of the burden of memorizing the database schema or having to look it up somewhere. 4.2 Execution Time The benefits of the SQL DOM come at a cost. The price we pay is increased time to construct SQL statements. Without the SQL DOM we simply manipulate strings to generate SQL statements. With the SQL DOM we are instantiating and manipulating a number of objects to generate SQL statements. To get an idea of the magnitude of the cost we incur, we ran three tests. In each of the three tests we compare the SQL DOM execution times with that of SQL string execution times, in the generation of identical SQL statements. To see how this cost changes with the size of the resulting SQL statement, each test contains five increasingly bigger versions of the same type of SQL statement. First we tested the time it takes to generate a simple select statement. Only the number of columns being selected was Figure 13. The IDE prompting the developer increased from 1 to 13. The results can be seen in Figure 15.

1400

1200

1000

800 DOM Strings Figure 14. The IDE prompting the developer 600 400 4. EVALUATION

ms per 10,000 generations 200 4.1 Benefits Before we subject our approach to a quantitative evaluation using 0 performance measurements in Section 4.2, we first summarize its 1471013 qualitative benefits. Number of select columns As shown in the preceding section, the SQL DOM together with the supporting tool, sqldomgen, allows detecting errors in code Figure 15. Performance test #1 that accesses the database during compile-time instead of at runtime. This has a direct impact on the reliability of the running Our second test also involved the generation of a select SQL system: runtime error messages and exceptions pertaining to the statement. However, this time the number of columns selected errors addressed above can be avoided. was constant and the number of where conditions were increased from 1 to 13. The results can be seen in Figure 16. The SQL DOM also impacts testability and maintainability of the overall code-base: unit tests no longer have to address typos and data type mismatches, and can focus on functionality instead. Maintenance is improved because the transition from one database schema to another is supported by the compiler and corresponding IDE.

93

4000 5. RELATED WORK SQLJ [4] and Embedded SQL [11] provide language extensions 3500 for Java and C respectively. SQL statements are written using 3000 these extensions in the same file as regular source code. Before being compiled by the regular language compiler, the file is 2500 DOM preprocessed. Among other steps, the preprocessor checks the 2000 SQL statements against a database schema for syntax and type Strings 1500 mismatch errors. The main disadvantage to these approaches is that they do not support dynamic SQL statements. Also, these 1000 approaches were never widely adopted. In fact, according to

ms per 10,000 generations 10,000 per ms 500 Oracle’s SQLJ Roadmap [19], future versions of their 0 development tools and database will no longer support SQLJ due 1471013 to lack of use. Number of where conditions Brant and Yoder [5] present a collection of patterns for developing applications that need to support user-configurable reports. Applications such as this would contain a great number of Figure 16. Performance test #2 dynamic SQL statements. Their patterns, Report Objects, Query The final test generated an update SQL statement. The number of Objects, Formula Objects, Composable Query Objects and columns being updated was increased from 1 to 13. The results Constraint Observers, provide a way to organize dynamic SQL can be seen in Figure 17. statements so that they are easily customizable to support user- configurable reports. Their work is similar to ours in that they propose using objects to construct and output SQL strings. 1400 However, they do not propose any sort of compile time checking 1200 of the validity of the generated SQL statements.

1000 Object/relational mapping [10, 15, 18] and persistent object systems [3, 7, 20] provide an object-oriented view of data stored 800 DOM in a relational database. Instead of querying the customers table 600 Strings and having a set of rows returned, you would have a collection of customer objects returned instead. The properties on the customer 400 object would correspond to the columns on the customers table. This is very useful and has a number of advantages including a

ms per 10,000 generations 200 familiar programming model and type safety. Although 0 abstracting away relational data behind a set of strongly-typed 1471013 objects is useful, it also results in the full power of the database Number of columns updated engine being obscured. This leads to the two main disadvantages of this approach, namely the loss of expressive power and

performance associated with directly accessing the database Figure 17. Performance test #3 engine through a call level interface. The results of all of the tests were in line with what we were Cook and Rai [9] introduce Safe Query Objects. Safe Query expecting to see. While in some cases the increase is a factor of Objects allow query behavior to be defined using strongly-typed 10 it is important to realize that the number being increased by objects and methods. In addition, safe query objects support query this factor is incredibly small. For example, consider the last data shipping by automatically generating code to execute queries point in Figure 16. The time to generate a single SQL statement is remotely in a relational database. Java Data Objects (JDO) is used increased from roughly .035 ms to .35 ms. This increase of .31 to provide the strongly-typed objects. This approach provides a ms would be unnoticeable when the cost of accessing the database way to efficiently execute strongly-typed queries that can be is taken into consideration. On our test machine, the cost of expressed in terms of the properties of strongly-typed objects. executing simple, static, SQL statements against a local database This is definitely a useful tool for those applications that will be averaged 180 ms. .35 ms is approximately .2% of 180 ms. So, using object/relational mapping or a persistent object system. while the increase in SQL generation times may look expensive, However, these approaches share the shortcomings we discussed when viewed in the context of database access it is virtually in the previous paragraph. unnoticeable. In our estimation, the performance cost does not come close to outweighing the benefits achieved by the SQL Gould, Su and Devanbu [12] present a different solution to the DOM. same problem we discuss in this paper: overcoming the problems associated with dynamically generating SQL statements. Their As yet, we have not spent any time optimizing the SQL DOM. approach is to statically analyze source code to locate where SQL We believe that the performance of the SQL DOM can be strings are being constructed. Each of the different possible substantially improved. resulting strings is then analyzed for syntax and type mismatch errors. Their approach has two notable advantages over our approach. Since all the analysis is performed statically, no

94

performance penalty is incurred. Their solution can also be used templates in any language that can then be manipulated on existing applications whereas our approach would require programmatically. Rewriting sqldomgen to use CodeSmith would existing applications to rewrite their SQL statement generation make it much easier to provide the SQL DOM to other object code using classes from the SQL DOM. However, performing oriented langauges such as Java. static checking leaves the developer powerless to defend against sqldomgen is run against a database schema. One of the inputs to SQL injection attacks. This would require dynamically analyzing sqldomgen is a connection string which is used to connect to the and possibly altering user input like we do in the SQL DOM. database. sqldomgen connects to the database to discover the Another advantage the SQL DOM has is that it offers developers schema. Allowing the schema to be specified in other ways, such development-time-support in the construction of SQL statements as an XSD file, will increase the flexibility of our approach via intellisense™. Also, mistakes made by the developer are further. caught by the compiler, not by a separate analyzer. This means developers never need to leave the confines of their favorite IDE The SQL DOM classes are manipulated to generate strings to find errors in their SQL statements. containing SQL statements. These strings are then passed by the developer through a call level interface to the database engine. Haskell/DB [16] is an effort to embed SQL in the functional We believe that a significant performance boost can be achieved programming language, Haskell. HaskellDB is similar to our by integrating the SQL DOM more closely with a call level approach in two ways. The first is that it provides an executable interface. Providing a way to take advantage of the parameterized to generate the necessary Haskell types which are used to create query support of the call level interface is an interesting SQL strings. This is similar to our sqldomgen. The other alternative to just generating strings. similarity is that the end result of their language extensions are SQL statements which are then passed to the database through a The final piece of future work we suggest pertains to other query call level interface. HaskellDB is also similar to the language languages. XPATH [8] is another query language where queries extensions mentioned above and therefore lacks support for are often constructed using string manipulations. Given an XSD dynamic SQL statements. Another notable difference is that for an XML document, one could generate a set of strongly-typed HaskellDB is designed to work with functional programming objects. These objects would then be manipulated to obtain an languages whereas the SQL DOM is designed to be used from XPATH query. This approach would give the same benefits to object oriented programming languages. dynamic XPATH queries as the SQL DOM gives to dynamic SQL statements. 6. CONCLUSION 6.1 Summary 7. ACKNOWLEDGEMENTS In this paper we have looked at the problems inherent in accessing Our work was partially supported by the UC Discovery Grant and relational databases from object oriented programming languages. the Industry-University Cooperative Research Program, as well as In particular, we have investigated the shortcomings of by funds from the California Institute for Telecommunications communicating with database engines through call level and Information Technology (Calit2). We are grateful to Alin interfaces. This communication requires the construction of Deutsch and the anonymous reviewers for insightful comments. dynamic SQL statements through string concatenation and string replacement. Creating SQL statements in this way can lead to a 8. REFERENCES number of problems, including run time errors, SQL injection [1] .NET Framework. http://msdn.microsoft.com/library/ attacks and code that is not easily maintainable. default.asp?url=/library/en-us/dnanchor/html/ To overcome these problems, we have introduced an object netfxanchor.asp, 2004. model, which we refer to as the SQL DOM. The SQL DOM [2] ADO.NET. http://msdn.microsoft.com/library/ allows SQL statements to be constructed through the default.asp?url=/library/en-us/cpguide/html/ manipulation of objects, which are strongly-typed to the database cpconaccessingdatawithadonet.asp, 2004. schema. [3] Atkinson, M. P., and Morrison, R. Orthogonally persistent 6.2 Future Work object systems. VLDB Journal, 4(3):319-401, 1995. There are a number of ways in which the SQL DOM can be [4] American National Standard for Information Technology. improved. Database languages – SQLJ – Part 1: SQL routines using the Java programming language. Technical Report It has been our experience that many applications use ANSI/INCITS 331.1-1999, InterNational Committee for object/relational mapping and call level interfaces in different Information Technology Standards (formerly NCITS), 1999. parts of the code. Integrating the SQL DOM with an object/relational mapper can provide a unified solution. [5] Brant, J., and Yoder, J. W. Creating reports with query objects. In Harrison, N., Foote, B., and Rohnert, H., editors, Currently, the classes that make up the SQL DOM are output as Pattern Languages of Program Design 4. Addison Wesley, C# source code using classes from the System.CodeDom 2000. namespace of the .NET Framework. At the time we were developing sqldomgen, this was the most familiar way to perform [6] C#. http://msdn.microsoft.com/vcsharp/, 2004. dynamic code generation. We have since come across a tool [7] Cengija, D. Hibernate your data. onJava.com, 2004. called CodeSmith [22]. CodeSmith allows the developer to write

95

[8] Clark, J., and DeRose, S. XML Path Language (XPath) Technical Report, Irsee, Germany, X. EA Generali, Vienna, Version 1.0. Technical report, W3C, 1999. Austria. [9] Cook, W., and Rai, S. Safe Query Objects: Statically-typed [16] Leijen, D., and Meijer, E., Domain specific embedded objects as remotely-executable queries. compilers. In Proceedings of the 2nd conference on Domain- http://www.cs.utexas.edu/users/wcook/Drafts/SafeQuery_Co specific languages, pages 109-122. ACM Press, 1999. okRai.pdf, 2004. [17] Maier, D. Representing database programs as objects. In [10] Dub, J. A., Sapir, R., and Purich, P. Oracle Application Bancilhon, F., and Buneman, P., editors, Advances in Server TopLink application developers guide, 10g (9.0.4). Database Programming Languages, Papers from DBPL-1, Oracle Corporation, 2003. September 1987, Roscoff, France, pages 377-386. ACM Press / Addison Wesley, 1987. [11] Embedded SQL for C. http://msdn.microsoft.com/library/ default.asp?url=/library/en-us/esqlforc/ [18] Matena, V., and Hapner, M. Enterprise Java Beans ec_6_epr_01_3m03.asp, 2004. Specification 1.0. Sun Microsystems, 1998. [12] Gould, C., Su, Z., and Devanbu, P. Static checking of [19] Oracle SQLJ Roadmap, http://www.oracle.com/ dynamically generated queries in database applications. In technology/tech/java/sqlj_jdbc/pdf/oracle_sqlj_roadmap.pdf, Proceedings, 26th International Conference on Software 2004. Engineering (ICSE). IEEE Press, 2004. [20] Russell, C. Java Data Objects (JDO) Specification JSR-12. [13] Hamilton, G., and Cattell, R. JDBC™ patterns. Sun Sun Microsystems, 1998 Microsystems, 2003. [21] Sanders, R. E. ODBC 3.5 Developer’s Guide. M&T Books, [14] Howard, M., and LeBlanc, D. Writing Secure Code, Second 1998. Edition, Microsoft Press, ch. 12, 2003. [22] Smith, E. J. CodeSmith. http://www.ericjsmith.net/ [15] Keller, W. Mapping objects to tables – a pattern language. In codesmith/, 2004. Proceedings of the 1997 European Pattern Languages of Programming Conference, number 120/SW1/FB in Siemens

96