You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Iciql.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. /*
  2. * Copyright 2004-2011 H2 Group.
  3. * Copyright 2011 James Moger.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package com.iciql;
  18. import java.lang.annotation.ElementType;
  19. import java.lang.annotation.Retention;
  20. import java.lang.annotation.RetentionPolicy;
  21. import java.lang.annotation.Target;
  22. /**
  23. * A class that implements this interface can be used as a database table.
  24. * <p>
  25. * You may implement the Table interface on your model object and optionally use
  26. * IQColumn annotations (which imposes a compile-time and runtime-dependency on
  27. * iciql), or may choose to use the IQTable and IQColumn annotations only (which
  28. * imposes a compile-time and runtime-dependency on this file only).
  29. * <p>
  30. * If a class is annotated with IQTable and at the same time implements Table,
  31. * the define() method is not called.
  32. * <p>
  33. * Fully Supported Data Types:
  34. * <table>
  35. * <tr>
  36. * <th colspan="2">All Databases</th>
  37. * </tr>
  38. * <tr>
  39. * <td>java.lang.String</td>
  40. * <td>VARCHAR (length > 0) or CLOB (length == 0)</td>
  41. * </tr>
  42. * <tr>
  43. * <td>java.lang.Boolean</td>
  44. * <td>BIT</td>
  45. * </tr>
  46. * <tr>
  47. * <td>java.lang.Byte</td>
  48. * <td>TINYINT</td>
  49. * </tr>
  50. * <tr>
  51. * <td>java.lang.Short</td>
  52. * <td>SMALLINT</td>
  53. * </tr>
  54. * <tr>
  55. * <td>java.lang.Integer</td>
  56. * <td>INT</td>
  57. * </tr>
  58. * <tr>
  59. * <td>java.lang.Long</td>
  60. * <td>BIGINT</td>
  61. * </tr>
  62. * <tr>
  63. * <td>java.lang.Float</td>
  64. * <td>REAL</td>
  65. * </tr>
  66. * <tr>
  67. * <td>java.lang.Double</td>
  68. * <td>DOUBLE</td>
  69. * </tr>
  70. * <tr>
  71. * <td>java.math.BigDecimal</td>
  72. * <td>DECIMAL (length == 0)<br/>
  73. * DECIMAL(length, scale) (length > 0)</td>
  74. * </tr>
  75. * <tr>
  76. * <td>java.sql.Date</td>
  77. * <td>DATE</td>
  78. * </tr>
  79. * <tr>
  80. * <td>java.sql.Time</td>
  81. * <td>TIME</td>
  82. * </tr>
  83. * <tr>
  84. * <td>java.sql.Timestamp</td>
  85. * <td>TIMESTAMP</td>
  86. * </tr>
  87. * <tr>
  88. * <td>java.util.Date</td>
  89. * <td>TIMESTAMP</td>
  90. * </tr>
  91. * <tr>
  92. * <td>java.lang.Enum.name()</td>
  93. * <td>VARCHAR (length > 0) or CLOB (length == 0)<br/>
  94. * EnumType.NAME</td>
  95. * </tr>
  96. * <tr>
  97. * <td>java.lang.Enum.ordinal()</td>
  98. * <td>INT<br/>
  99. * EnumType.ORDINAL</td>
  100. * </tr>
  101. * <tr>
  102. * <td>java.lang.Enum implements<br/>
  103. * com.iciql.Iciql.EnumID.enumId()</td>
  104. * <td>INT<br/>
  105. * EnumType.ENUMID</td>
  106. * </tr>
  107. * <tr>
  108. * <th colspan="2">H2 Databases</th>
  109. * </tr>
  110. * <tr>
  111. * <td>java.util.UUID</td>
  112. * <td>UUID</td>
  113. * </tr>
  114. * </table>
  115. * <p>
  116. * Partially Supported Data Types:
  117. * <p>
  118. * The following data types can be mapped to columns for all general statements
  119. * BUT these field types may not be used to specify compile-time clauses or
  120. * constraints.
  121. * <table>
  122. * <tr>
  123. * <td>byte []</td>
  124. * <td>BLOB</td>
  125. * </tr>
  126. * <tr>
  127. * <td>boolean</td>
  128. * <td>BIT</td>
  129. * </tr>
  130. * <tr>
  131. * <td>byte</td>
  132. * <td>TINYINT</td>
  133. * </tr>
  134. * <tr>
  135. * <td>short</td>
  136. * <td>SMALLINT</td>
  137. * </tr>
  138. * <tr>
  139. * <td>int</td>
  140. * <td>INT</td>
  141. * </tr>
  142. * <tr>
  143. * <td>long</td>
  144. * <td>BIGINT</td>
  145. * </tr>
  146. * <tr>
  147. * <td>float</td>
  148. * <td>REAL</td>
  149. * </tr>
  150. * <tr>
  151. * <td>double</td>
  152. * <td>DOUBLE</td>
  153. * </tr>
  154. * </table>
  155. * <p>
  156. * Table and field mapping: by default, the mapped table name is the class name
  157. * and the public fields are reflectively mapped, by their name, to columns. As
  158. * an alternative, you may specify both the table and column definition by
  159. * annotations.
  160. * <p>
  161. * Table Interface: you may set additional parameters such as table name,
  162. * primary key, and indexes in the define() method.
  163. * <p>
  164. * Annotations: you may use the annotations with or without implementing the
  165. * Table interface. The annotations allow you to decouple your model completely
  166. * from iciql other than this file.
  167. * <p>
  168. * Automatic model generation: you may automatically generate model classes as
  169. * strings with the Db and DbInspector objects:
  170. *
  171. * <pre>
  172. * Db db = Db.open(&quot;jdbc:h2:mem:&quot;, &quot;sa&quot;, &quot;sa&quot;);
  173. * DbInspector inspector = new DbInspector(db);
  174. * List&lt;String&gt; models =
  175. * inspector.generateModel(schema, table, packageName,
  176. * annotateSchema, trimStrings)
  177. * </pre>
  178. *
  179. * Or you may use the GenerateModels tool to generate and save your classes to
  180. * the file system:
  181. *
  182. * <pre>
  183. * java -jar iciql.jar
  184. * -url &quot;jdbc:h2:mem:&quot;
  185. * -user sa -password sa -schema schemaName -table tableName
  186. * -package packageName -folder destination
  187. * -annotateSchema false -trimStrings true
  188. * </pre>
  189. *
  190. * Model validation: you may validate your model class with DbInspector object.
  191. * The DbInspector will report errors, warnings, and suggestions:
  192. *
  193. * <pre>
  194. * Db db = Db.open(&quot;jdbc:h2:mem:&quot;, &quot;sa&quot;, &quot;sa&quot;);
  195. * DbInspector inspector = new DbInspector(db);
  196. * List&lt;Validation&gt; remarks = inspector.validateModel(new MyModel(), throwOnError);
  197. * for (Validation remark : remarks) {
  198. * System.out.println(remark);
  199. * }
  200. * </pre>
  201. */
  202. public interface Iciql {
  203. /**
  204. * An annotation for an iciql version.
  205. * <p>
  206. *
  207. * @IQVersion(1)
  208. */
  209. @Retention(RetentionPolicy.RUNTIME)
  210. @Target(ElementType.TYPE)
  211. public @interface IQVersion {
  212. /**
  213. * If set to a non-zero value, iciql maintains a "_iq_versions" table
  214. * within your database. The version number is used to call to a
  215. * registered DbUpgrader implementation to perform relevant ALTER
  216. * statements. Default: 0. You must specify a DbUpgrader on your Db
  217. * object to use this parameter.
  218. */
  219. int value() default 0;
  220. }
  221. /**
  222. * An annotation for a schema.
  223. * <p>
  224. *
  225. * @IQSchema("PUBLIC")
  226. */
  227. @Retention(RetentionPolicy.RUNTIME)
  228. @Target(ElementType.TYPE)
  229. public @interface IQSchema {
  230. /**
  231. * The schema may be optionally specified. Default: unspecified.
  232. */
  233. String value() default "";
  234. }
  235. /**
  236. * Enumeration defining the four index types.
  237. */
  238. public static enum IndexType {
  239. STANDARD, UNIQUE, HASH, UNIQUE_HASH;
  240. }
  241. /**
  242. * An index annotation.
  243. * <p>
  244. * <ul>
  245. * <li>@IQIndex("name")
  246. * <li>@IQIndex({"street", "city"})
  247. * <li>@IQIndex(name="streetidx", value={"street", "city"})
  248. * <li>@IQIndex(name="addressidx", type=IndexType.UNIQUE,
  249. * value={"house_number", "street", "city"})
  250. * </ul>
  251. */
  252. @Retention(RetentionPolicy.RUNTIME)
  253. @Target(ElementType.TYPE)
  254. public @interface IQIndex {
  255. /**
  256. * Index name. If null or empty, iciql will generate one.
  257. */
  258. String name() default "";
  259. /**
  260. * Type of the index.
  261. * <ul>
  262. * <li>com.iciql.iciql.IndexType.STANDARD
  263. * <li>com.iciql.iciql.IndexType.UNIQUE
  264. * <li>com.iciql.iciql.IndexType.HASH
  265. * <li>com.iciql.iciql.IndexType.UNIQUE_HASH
  266. * </ul>
  267. *
  268. * HASH indexes may only be valid for single column indexes.
  269. *
  270. */
  271. IndexType type() default IndexType.STANDARD;
  272. /**
  273. * Columns to include in index.
  274. * <ul>
  275. * <li>single column index: value = "id"
  276. * <li>multiple column index: value = { "id", "name", "date" }
  277. * </ul>
  278. */
  279. String[] value() default {};
  280. }
  281. /**
  282. * Annotation to specify multiple indexes.
  283. */
  284. @Retention(RetentionPolicy.RUNTIME)
  285. @Target(ElementType.TYPE)
  286. public @interface IQIndexes {
  287. IQIndex[] value() default {};
  288. }
  289. /**
  290. * Annotation to define a table.
  291. */
  292. @Retention(RetentionPolicy.RUNTIME)
  293. @Target(ElementType.TYPE)
  294. public @interface IQTable {
  295. /**
  296. * The table name. If not specified the class name is used as the table
  297. * name.
  298. * <p>
  299. * The table name may still be overridden in the define() method if the
  300. * model class is not annotated with IQTable. Default: unspecified.
  301. */
  302. String name() default "";
  303. /**
  304. * The primary key may be optionally specified. If it is not specified,
  305. * then no primary key is set by the IQTable annotation. You may specify
  306. * a composite primary key.
  307. * <ul>
  308. * <li>single column primaryKey: value = "id"
  309. * <li>compound primary key: value = { "id", "name" }
  310. * </ul>
  311. * The primary key may still be overridden in the define() method if the
  312. * model class is not annotated with IQTable. Default: unspecified.
  313. */
  314. String[] primaryKey() default {};
  315. /**
  316. * The inherit columns allows this model class to inherit columns from
  317. * its super class. Any IQTable annotation present on the super class is
  318. * ignored. Default: false.
  319. */
  320. boolean inheritColumns() default false;
  321. /**
  322. * Whether or not iciql tries to create the table and indexes. Default:
  323. * true.
  324. */
  325. boolean create() default true;
  326. /**
  327. * If true, only fields that are explicitly annotated as IQColumn are
  328. * mapped. Default: true.
  329. */
  330. boolean annotationsOnly() default true;
  331. /**
  332. * If true, this table is created as a memory table where data is
  333. * persistent, but index data is kept in main memory. Valid only for H2
  334. * databases. Default: false.
  335. */
  336. boolean memoryTable() default false;
  337. }
  338. /**
  339. * Annotation to define a column. Annotated fields may have any scope
  340. * (however, the JVM may raise a SecurityException if the SecurityManager
  341. * doesn't allow iciql to access the field.)
  342. */
  343. @Retention(RetentionPolicy.RUNTIME)
  344. @Target(ElementType.FIELD)
  345. public @interface IQColumn {
  346. /**
  347. * If not specified, the field name is used as the column name. Default:
  348. * the field name.
  349. */
  350. String name() default "";
  351. /**
  352. * This column is the primary key. Default: false.
  353. */
  354. boolean primaryKey() default false;
  355. /**
  356. * The column is created with a sequence as the default value. Default:
  357. * false.
  358. */
  359. boolean autoIncrement() default false;
  360. /**
  361. * Length is used to define the length of a VARCHAR column or to define
  362. * the precision of a DECIMAL(precision, scale) expression.
  363. * <p>
  364. * If larger than zero, it is used during the CREATE TABLE phase. For
  365. * string values it may also be used to prevent database exceptions on
  366. * INSERT and UPDATE statements (see trim).
  367. * <p>
  368. * Any length set in define() may override this annotation setting if
  369. * the model class is not annotated with IQTable. Default: 0.
  370. */
  371. int length() default 0;
  372. /**
  373. * Scale is used during the CREATE TABLE phase to define the scale of a
  374. * DECIMAL(precision, scale) expression.
  375. * <p>
  376. * Any scale set in define() may override this annotation setting if the
  377. * model class is not annotated with IQTable. Default: 0.
  378. */
  379. int scale() default 0;
  380. /**
  381. * If true, iciql will automatically trim the string if it exceeds
  382. * length (value.substring(0, length)). Default: false.
  383. */
  384. boolean trim() default false;
  385. /**
  386. * If false, iciql will set the column NOT NULL during the CREATE TABLE
  387. * phase. Default: true.
  388. */
  389. boolean nullable() default true;
  390. /**
  391. * The default value assigned to the column during the CREATE TABLE
  392. * phase. This field could contain a literal single-quoted value, or a
  393. * function call. Empty strings are considered NULL. Examples:
  394. * <ul>
  395. * <li>defaultValue="" (null)
  396. * <li>defaultValue="CURRENT_TIMESTAMP"
  397. * <li>defaultValue="''" (empty string)
  398. * <li>defaultValue="'0'"
  399. * <li>defaultValue="'1970-01-01 00:00:01'"
  400. * </ul>
  401. * if the default value is specified, and auto increment is disabled,
  402. * and primary key is disabled, then this value is included in the
  403. * "DEFAULT ..." phrase of a column during the CREATE TABLE process.
  404. * <p>
  405. * Alternatively, you may specify a default object value on the field
  406. * and this will be converted to a properly formatted DEFAULT expression
  407. * during the CREATE TABLE process.
  408. * <p>
  409. * Default: unspecified (null).
  410. */
  411. String defaultValue() default "";
  412. }
  413. /**
  414. * Interface for using the EnumType.ENUMID enumeration mapping strategy.
  415. * <p>
  416. * Enumerations wishing to use EnumType.ENUMID must implement this
  417. * interface.
  418. */
  419. public interface EnumId {
  420. int enumId();
  421. }
  422. /**
  423. * Enumeration representing how to map a java.lang.Enum to a column.
  424. * <p>
  425. * <ul>
  426. * <li>NAME - name() : string
  427. * <li>ORDINAL - ordinal() : int
  428. * <li>ENUMID - enumId() : int
  429. * </ul>
  430. *
  431. * @see com.iciql.Iciql.EnumId interface
  432. */
  433. public enum EnumType {
  434. NAME, ORDINAL, ENUMID;
  435. public static final EnumType DEFAULT_TYPE = NAME;
  436. }
  437. /**
  438. * Annotation to define how a java.lang.Enum is mapped to a column.
  439. * <p>
  440. * This annotation can be used on:
  441. * <ul>
  442. * <li>a field instance of an enumeration type
  443. * <li>on the enumeration class declaration
  444. * </ul>
  445. * If you choose to annotate the class declaration, that will be the default
  446. * mapping strategy for all @IQColumn instances of the enum. This can still
  447. * be overridden for an individual field by specifying the IQEnum
  448. * annotation.
  449. * <p>
  450. * The default mapping is by NAME.
  451. *
  452. * <pre>
  453. * IQEnum(EnumType.NAME)
  454. * </pre>
  455. *
  456. * A string mapping will generate either a VARCHAR, if IQColumn.length > 0
  457. * or a TEXT column if IQColumn.length == 0
  458. *
  459. */
  460. @Retention(RetentionPolicy.RUNTIME)
  461. @Target({ ElementType.FIELD, ElementType.TYPE })
  462. public @interface IQEnum {
  463. EnumType value() default EnumType.NAME;
  464. }
  465. /**
  466. * This method is called to let the table define the primary key, indexes,
  467. * and the table name.
  468. */
  469. @Deprecated
  470. void defineIQ();
  471. }