DBLocalDate.java

  1. /*
  2.  * Copyright 2013 Gregory Graham.
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package nz.co.gregs.dbvolution.datatypes;

  17. import java.sql.Date;
  18. import java.sql.ResultSet;
  19. import java.sql.SQLException;
  20. import java.sql.Timestamp;
  21. import java.text.ParseException;
  22. import java.time.LocalDate;
  23. import java.time.format.DateTimeFormatter;
  24. import java.time.format.DateTimeParseException;
  25. import java.util.Comparator;
  26. import java.util.HashSet;
  27. import java.util.Set;
  28. import nz.co.gregs.dbvolution.DBReport;
  29. import nz.co.gregs.dbvolution.DBRow;
  30. import nz.co.gregs.dbvolution.columns.LocalDateColumn;
  31. import nz.co.gregs.dbvolution.databases.SQLiteDB;
  32. import nz.co.gregs.dbvolution.databases.definitions.DBDefinition;
  33. import nz.co.gregs.dbvolution.exceptions.DBRuntimeException;
  34. import nz.co.gregs.dbvolution.exceptions.IncorrectRowProviderInstanceSuppliedException;
  35. import nz.co.gregs.dbvolution.expressions.LocalDateExpression;
  36. import nz.co.gregs.dbvolution.expressions.StringExpression;
  37. import nz.co.gregs.dbvolution.operators.DBGreaterThanOperator;
  38. import nz.co.gregs.dbvolution.operators.DBGreaterThanOrEqualsOperator;
  39. import nz.co.gregs.dbvolution.operators.DBLessThanOperator;
  40. import nz.co.gregs.dbvolution.operators.DBLessThanOrEqualOperator;
  41. import nz.co.gregs.dbvolution.operators.DBPermittedRangeExclusiveOperator;
  42. import nz.co.gregs.dbvolution.operators.DBPermittedRangeInclusiveOperator;
  43. import nz.co.gregs.dbvolution.operators.DBPermittedRangeOperator;
  44. import nz.co.gregs.dbvolution.operators.DBPermittedValuesOperator;
  45. import nz.co.gregs.dbvolution.query.RowDefinition;
  46. import nz.co.gregs.dbvolution.results.LocalDateResult;
  47. import nz.co.gregs.dbvolution.utility.comparators.ComparableComparator;

  48. /**
  49.  * Encapsulates database values that are Dates.
  50.  *
  51.  * <p>
  52.  * Use DBDate when the column is a date datatype, even in databases where the
  53.  * native date type is a String (i.e. {@link SQLiteDB}).
  54.  *
  55.  * <p>
  56.  * Generally DBDate is declared inside your DBRow sub-class as:
  57.  * {@code @DBColumn public DBDate myBoolColumn = new DBDate();}
  58.  *
  59.  * <p style="color: #F90;">Support DBvolution at
  60.  * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  61.  *
  62.  * @author Gregory Graham
  63.  */
  64. public class DBLocalDate extends QueryableDatatype<LocalDate> implements LocalDateResult {

  65.     private static final long serialVersionUID = 1L;
  66.     private final DateTimeFormatter toStringFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");

  67.     /**
  68.      * The default constructor for DBDate.
  69.      *
  70.      * <p>
  71.      * Creates an unset undefined DBDate object.
  72.      *
  73.      */
  74.     public DBLocalDate() {
  75.         super();
  76.     }

  77.     /**
  78.      * Creates a DBDate with the value provided.
  79.      *
  80.      * <p>
  81.      * The resulting DBDate will be set as having the value provided but will not
  82.      * be defined in the database.
  83.      *
  84.      * @param date  date
  85.      */
  86.     public DBLocalDate(LocalDate date) {
  87.         super(date);
  88.     }

  89.     /**
  90.      * Creates a column expression with a date result from the expression
  91.      * provided.
  92.      *
  93.      * <p>
  94.      * Used in {@link DBReport}, and some {@link DBRow}, sub-classes to derive
  95.      * data from the database prior to retrieval.
  96.      *
  97.      * @param dateExpression    dateExpression
  98.      */
  99.     public DBLocalDate(LocalDateExpression dateExpression) {
  100.         super(dateExpression);
  101.     }

  102.     /**
  103.      * Creates a DBDate with the value provided.
  104.      *
  105.      * <p>
  106.      * The resulting DBDate will be set as having the value provided but will not
  107.      * be defined in the database.
  108.      *
  109.      *
  110.      */
  111.     DBLocalDate(Timestamp timestamp) {
  112.         super(timestamp == null ? null : timestamp.toLocalDateTime().toLocalDate());
  113.         if (timestamp == null) {
  114.             this.setToNull();
  115.         } else {
  116.             setLiteralValue(timestamp.toLocalDateTime().toLocalDate());
  117.         }
  118.     }

  119.     /**
  120.      * Creates a DBDate with the value provided.
  121.      *
  122.      * <p>
  123.      * The resulting DBDate will be set as having the value provided but will not
  124.      * be defined in the database.
  125.      *
  126.      * <p>
  127.      * The string is parsed using {@link LocalDate#parse(java.lang.String) } so
  128.      * please ensure your string matches the requirements of that method.
  129.      *
  130.      *
  131.      */
  132.     @SuppressWarnings("deprecation")
  133.     DBLocalDate(String dateAsAString) {
  134.         final LocalDate dateValue = LocalDate.parse(dateAsAString);
  135.         setLiteralValue(dateValue);
  136.     }

  137.     /**
  138.      * Returns the set value of this DBDate as a Java LocalDate instance.
  139.      *
  140.      * <p style="color: #F90;">Support DBvolution at
  141.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  142.      *
  143.      * @return the value as a Java LocalDate.
  144.      */
  145.     public LocalDate localDateValue() {
  146.         if (getLiteralValue() instanceof LocalDate) {
  147.             return getLiteralValue();
  148.         } else {
  149.             return null;
  150.         }
  151.     }

  152.     void setValue(DBLocalDate newLiteralValue) {
  153.         setValue(newLiteralValue.getLiteralValue());
  154.     }

  155.     /**
  156.      * Sets the value of this QDT to the Java LocalDate provided.
  157.      *
  158.      * @param date  date
  159.      */
  160.     @Override
  161.     public void setValue(LocalDate date) {
  162.         super.setLiteralValue(date);
  163.     }

  164.     /**
  165.      * Sets the value of this QDT to the date and time now.
  166.      *
  167.      */
  168.     public void setValueToNow() {
  169.         super.setValue(LocalDate.now());
  170.     }

  171.     /**
  172.      * Sets the value of this QDT to the dateStr provided.
  173.      *
  174.      * <p>
  175.      * The date String will be parsed by {@link LocalDate#parse(java.lang.CharSequence)
  176.      * }
  177.      * so please confirms to the requirements of that method.
  178.      *
  179.      * @param dateStr   dateStr
  180.      */
  181.     @SuppressWarnings("deprecation")
  182.     public void setValue(String dateStr) {
  183.         final LocalDate date = LocalDate.parse(dateStr);
  184.         setValue(date);
  185.     }

  186.     @Override
  187.     public String getSQLDatatype() {
  188.         return "TIMESTAMP";
  189.     }

  190.     /**
  191.      * Returns the string value of the DBDate.
  192.      *
  193.      * <p style="color: #F90;">Support DBvolution at
  194.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  195.      *
  196.      * @return a string version of the current value of this DBDate
  197.      */
  198.     @Override
  199.     public String toString() {
  200.         if (this.isNull() || localDateValue() == null) {
  201.             return "<NULL>";
  202.         }
  203.         return DateTimeFormatter.ISO_LOCAL_DATE.format(localDateValue());
  204.     }

  205.     @Override
  206.     public String formatValueForSQLStatement(DBDefinition db) {
  207.         return db.getLocalDateFormattedForQuery(localDateValue());
  208.     }

  209.     @Override
  210.     protected LocalDate getFromResultSet(DBDefinition defn, ResultSet resultSet, String fullColumnName) {
  211.         LocalDate dbValue;
  212.         if (defn.prefersDatesReadAsStrings()) {
  213.             dbValue = setByGetString(defn, resultSet, fullColumnName);
  214.         } else {
  215.             dbValue = setByGetDate(defn, resultSet, fullColumnName);
  216.         }
  217.         return dbValue;
  218.     }

  219.     private LocalDate setByGetString(DBDefinition database, ResultSet resultSet, String fullColumnName) {
  220.         String string = null;
  221.         try {
  222.             string = resultSet.getString(fullColumnName);
  223.         } catch (SQLException sqlex) {
  224.             throw new DBRuntimeException("Unable to get LocalDate from String:" + sqlex.getLocalizedMessage(), sqlex);
  225.         }
  226.         if (string == null || string.isEmpty()) {
  227.             return null;
  228.         } else {
  229.             return database.parseLocalDateFromGetString(string);
  230.         }
  231.     }

  232.     private LocalDate setByGetDate(DBDefinition defn, ResultSet resultSet, String fullColumnName) {
  233.         LocalDate dbValue = null;
  234.         try {
  235.             final Date date = resultSet.getDate(fullColumnName);
  236.             if (resultSet.wasNull()) {
  237.                 dbValue = null;
  238.             } else {
  239.                 LocalDate dateValue = date.toLocalDate();
  240.                 // Some drivers interpret getDate as meaning return only the date without the time
  241.                 // so we should check both the date and the timestamp find the latest time.
  242.                 final Timestamp timestamp = resultSet.getTimestamp(fullColumnName);
  243.                 LocalDate timestampValue = timestamp.toLocalDateTime().toLocalDate();
  244.                 if (timestampValue.isAfter(dateValue)) {
  245.                     dbValue = timestampValue;
  246.                 } else {
  247.                     dbValue = dateValue;
  248.                 }
  249.             }
  250.         } catch (SQLException sqlex) {
  251.             throw new DBRuntimeException("Unable to set LocalDate by getting LocalDate: " + sqlex.getLocalizedMessage(), sqlex);
  252.         }
  253.         return dbValue;
  254.     }

  255.     @Override
  256.     public DBLocalDate copy() {
  257.         return (DBLocalDate) super.copy();
  258.     }

  259.     @Override
  260.     public LocalDate getValue() {
  261.         return localDateValue();
  262.     }

  263.     @Override
  264.     public DBLocalDate getQueryableDatatypeForExpressionValue() {
  265.         return new DBLocalDate();
  266.     }

  267.     @Override
  268.     public boolean isAggregator() {
  269.         return false;
  270.     }

  271.     @Override
  272.     public Set<DBRow> getTablesInvolved() {
  273.         return new HashSet<>();
  274.     }

  275.     /**
  276.      *
  277.      * reduces the rows to only the object, Set, List, Array, or vararg of objects
  278.      *
  279.      * @param permitted permitted
  280.      */
  281.     public void permittedValues(LocalDate... permitted) {
  282.         this.setOperator(new DBPermittedValuesOperator<LocalDate>(permitted));
  283.     }

  284.     /**
  285.      *
  286.      * excludes the object, Set, List, Array, or vararg of objects
  287.      *
  288.      *
  289.      * @param excluded  excluded
  290.      */
  291.     public void excludedValues(LocalDate... excluded) {
  292.         this.setOperator(new DBPermittedValuesOperator<LocalDate>(excluded));
  293.         negateOperator();
  294.     }

  295.     /**
  296.      * Performs searches based on a range.
  297.      *
  298.      * if both ends of the range are specified the lower-bound will be included in
  299.      * the search and the upper-bound excluded. I.e permittedRange(1,3) will
  300.      * return 1 and 2.
  301.      *
  302.      * <p>
  303.      * if the upper-bound is null the range will be open ended upwards and
  304.      * inclusive.
  305.      * <br>
  306.      * I.e permittedRange(1,null) will return 1,2,3,4,5, etc.
  307.      *
  308.      * <p>
  309.      * if the lower-bound is null the range will be open ended downwards and
  310.      * exclusive.
  311.      * <br>
  312.      * I.e permittedRange(null, 5) will return 4,3,2,1, etc.
  313.      *
  314.      * @param lowerBound lowerBound
  315.      * @param upperBound upperBound
  316.      */
  317.     public void permittedRange(LocalDate lowerBound, LocalDate upperBound) {
  318.         setOperator(new DBPermittedRangeOperator<LocalDate>(lowerBound, upperBound));
  319.     }

  320.     /**
  321.      * Performs searches based on a range.
  322.      *
  323.      * if both ends of the range are specified both the lower- and upper-bound
  324.      * will be included in the search. I.e permittedRangeInclusive(1,3) will
  325.      * return 1, 2, and 3.
  326.      *
  327.      * <p>
  328.      * if the upper-bound is null the range will be open ended upwards and
  329.      * inclusive.
  330.      * <br>
  331.      * I.e permittedRangeInclusive(1,null) will return 1,2,3,4,5, etc.
  332.      *
  333.      * <p>
  334.      * if the upper-bound is null the range will be open ended downwards and
  335.      * inclusive.
  336.      * <br>
  337.      * I.e permittedRangeInclusive(null, 5) will return 5,4,3,2,1, etc.
  338.      *
  339.      * @param lowerBound lowerBound
  340.      * @param upperBound upperBound
  341.      */
  342.     public void permittedRangeInclusive(LocalDate lowerBound, LocalDate upperBound) {
  343.         setOperator(new DBPermittedRangeInclusiveOperator(lowerBound, upperBound));
  344.     }

  345.     /**
  346.      * Performs searches based on a range.
  347.      *
  348.      * if both ends of the range are specified both the lower- and upper-bound
  349.      * will be excluded in the search. I.e permittedRangeExclusive(1,3) will
  350.      * return 2.
  351.      *
  352.      * <p>
  353.      * if the upper-bound is null the range will be open ended upwards and
  354.      * exclusive.
  355.      * <br>
  356.      * I.e permittedRangeExclusive(1,null) will return 2,3,4,5,...
  357.      *
  358.      * <p>
  359.      * if the upper-bound is null the range will be open ended downwards and
  360.      * exclusive.
  361.      * <br>
  362.      * I.e permittedRangeExclusive(null, 5) will return 4,3,2,1,...
  363.      *
  364.      * @param lowerBound lowerBound
  365.      * @param upperBound upperBound
  366.      */
  367.     public void permittedRangeExclusive(LocalDate lowerBound, LocalDate upperBound) {
  368.         setOperator(new DBPermittedRangeExclusiveOperator(lowerBound, upperBound));
  369.     }

  370.     /**
  371.      * Performs searches based on a range.
  372.      *
  373.      * if both ends of the range are specified the lower-bound will be included in
  374.      * the search and the upper-bound excluded. I.e excludedRange(1,3) will return
  375.      * everything except 1 and 2.
  376.      *
  377.      * <p>
  378.      * if the upper-bound is null the range will be open ended upwards and
  379.      * inclusive.
  380.      * <br>
  381.      * I.e excludedRange(1,null) will return ..., -1, 0.
  382.      *
  383.      * <p>
  384.      * if the lower-bound is null the range will be open ended downwards and
  385.      * exclusive.
  386.      * <br>
  387.      * I.e excludedRange(null, 5) will return 5, 6, 7, 8 etc.
  388.      *
  389.      * @param lowerBound lowerBound
  390.      * @param upperBound upperBound
  391.      */
  392.     public void excludedRange(LocalDate lowerBound, LocalDate upperBound) {
  393.         setOperator(new DBPermittedRangeOperator<LocalDate>(lowerBound, upperBound));
  394.         negateOperator();
  395.     }

  396.     /**
  397.      * Performs searches based on a range.
  398.      *
  399.      * if both ends of the range are specified both the lower- and upper-bound
  400.      * will be included in the search. I.e excludedRangeInclusive(1,3) will return
  401.      * ..., -1, 0, 4, 5, ... .
  402.      *
  403.      * <p>
  404.      * if the upper-bound is null the range will be open ended upwards and
  405.      * inclusive.
  406.      * <br>
  407.      * I.e excludedRangeInclusive(1,null) will return ..., -1, 0.
  408.      *
  409.      * <p>
  410.      * if the upper-bound is null the range will be open ended downwards and
  411.      * inclusive.
  412.      * <br>
  413.      * I.e excludedRangeInclusive(null, 5) will return 6, 7, 8, 9,... etc.
  414.      *
  415.      * @param lowerBound lowerBound
  416.      * @param upperBound upperBound
  417.      */
  418.     public void excludedRangeInclusive(LocalDate lowerBound, LocalDate upperBound) {
  419.         setOperator(new DBPermittedRangeInclusiveOperator(lowerBound, upperBound));
  420.         negateOperator();
  421.     }

  422.     /**
  423.      * Performs searches based on a range.
  424.      *
  425.      * if both ends of the range are specified both the lower- and upper-bound
  426.      * will be excluded in the search. I.e excludedRangeExclusive(1,3) will return
  427.      * ... -1, 0, 1, 3, 4,... but exclude 2.
  428.      *
  429.      * <p>
  430.      * if the upper-bound is null the range will be open ended upwards and
  431.      * exclusive.
  432.      * <br>
  433.      * I.e excludedRangeExclusive(1,null) will return ..., -1 ,0 ,1 .
  434.      *
  435.      * <p>
  436.      * if the upper-bound is null the range will be open ended downwards and
  437.      * exclusive.
  438.      * <br>
  439.      * I.e excludedRangeExclusive(null, 5) will return 5,6,7,8...
  440.      *
  441.      * @param lowerBound lowerBound
  442.      * @param upperBound upperBound
  443.      */
  444.     public void excludedRangeExclusive(LocalDate lowerBound, LocalDate upperBound) {
  445.         setOperator(new DBPermittedRangeExclusiveOperator(lowerBound, upperBound));
  446.         negateOperator();
  447.     }

  448.     /**
  449.      *
  450.      * reduces the rows to only the object, Set, List, Array, or vararg of objects
  451.      *
  452.      * @param permitted permitted
  453.      */
  454.     public void permittedValues(LocalDateExpression... permitted) {
  455.         this.setOperator(new DBPermittedValuesOperator<LocalDateExpression>(permitted));
  456.     }

  457.     /**
  458.      *
  459.      * excludes the object, Set, List, Array, or vararg of objects
  460.      *
  461.      *
  462.      * @param excluded  excluded
  463.      */
  464.     public void excludedValues(LocalDateExpression... excluded) {
  465.         this.setOperator(new DBPermittedValuesOperator<LocalDateExpression>(excluded));
  466.         negateOperator();
  467.     }

  468.     /**
  469.      * Performs searches based on a range.
  470.      *
  471.      * if both ends of the range are specified the lower-bound will be included in
  472.      * the search and the upper-bound excluded. I.e permittedRange(1,3) will
  473.      * return 1 and 2.
  474.      *
  475.      * <p>
  476.      * if the upper-bound is null the range will be open ended upwards and
  477.      * inclusive.
  478.      * <br>
  479.      * I.e permittedRange(1,null) will return 1,2,3,4,5, etc.
  480.      *
  481.      * <p>
  482.      * if the lower-bound is null the range will be open ended downwards and
  483.      * exclusive.
  484.      * <br>
  485.      * I.e permittedRange(null, 5) will return 4,3,2,1, etc.
  486.      *
  487.      * @param lowerBound lowerBound
  488.      * @param upperBound upperBound
  489.      */
  490.     public void permittedRange(LocalDateExpression lowerBound, LocalDateExpression upperBound) {
  491.         setOperator(new DBPermittedRangeOperator<LocalDateExpression>(lowerBound, upperBound));
  492.     }

  493.     /**
  494.      * Performs searches based on a range.
  495.      *
  496.      * if both ends of the range are specified both the lower- and upper-bound
  497.      * will be included in the search. I.e permittedRangeInclusive(1,3) will
  498.      * return 1, 2, and 3.
  499.      *
  500.      * <p>
  501.      * if the upper-bound is null the range will be open ended upwards and
  502.      * inclusive.
  503.      * <br>
  504.      * I.e permittedRangeInclusive(1,null) will return 1,2,3,4,5, etc.
  505.      *
  506.      * <p>
  507.      * if the lower-bound is null the range will be open ended downwards and
  508.      * inclusive.
  509.      * <br>
  510.      * I.e permittedRangeInclusive(null, 5) will return 5,4,3,2,1, etc.
  511.      *
  512.      * @param lowerBound lowerBound
  513.      * @param upperBound upperBound
  514.      */
  515.     public void permittedRangeInclusive(LocalDateExpression lowerBound, LocalDateExpression upperBound) {
  516.         setOperator(new DBPermittedRangeInclusiveOperator(lowerBound, upperBound));
  517.     }

  518.     /**
  519.      * Performs searches based on a range.
  520.      *
  521.      * if both ends of the range are specified both the lower- and upper-bound
  522.      * will be excluded in the search. I.e permittedRangeExclusive(1,3) will
  523.      * return 2.
  524.      *
  525.      * <p>
  526.      * if the upper-bound is null the range will be open ended upwards and
  527.      * exclusive.
  528.      * <br>
  529.      * I.e permittedRangeExclusive(1,null) will return 2,3,4,5, etc.
  530.      *
  531.      * <p>
  532.      * if the lower-bound is null the range will be open ended downwards and
  533.      * exclusive.
  534.      * <br>
  535.      * I.e permittedRangeExclusive(null, 5) will return 4,3,2,1, etc.
  536.      *
  537.      * @param lowerBound lowerBound
  538.      * @param upperBound upperBound
  539.      */
  540.     public void permittedRangeExclusive(LocalDateExpression lowerBound, LocalDateExpression upperBound) {
  541.         setOperator(new DBPermittedRangeExclusiveOperator(lowerBound, upperBound));
  542.     }

  543.     /**
  544.      * Performs searches based on a range.
  545.      *
  546.      * if both ends of the range are specified the lower-bound will be included in
  547.      * the search and the upper-bound excluded. I.e excludedRange(1,3) will return
  548.      * everything except 1 and 2.
  549.      *
  550.      * <p>
  551.      * if the upper-bound is null the range will be open ended upwards and
  552.      * inclusive.
  553.      * <br>
  554.      * I.e excludedRange(1,null) will return 0, -1, -2, etc.
  555.      *
  556.      * <p>
  557.      * if the lower-bound is null the range will be open ended downwards and
  558.      * exclusive.
  559.      * <br>
  560.      * I.e excludedRange(null, 5) will return 5, 6, 7, 8, etc.
  561.      *
  562.      * @param lowerBound lowerBound
  563.      * @param upperBound upperBound
  564.      */
  565.     public void excludedRange(LocalDateExpression lowerBound, LocalDateExpression upperBound) {
  566.         setOperator(new DBPermittedRangeOperator<LocalDateExpression>(lowerBound, upperBound));
  567.         negateOperator();
  568.     }

  569.     /**
  570.      * Performs searches based on a range.
  571.      *
  572.      * if both ends of the range are specified both the lower- and upper-bound
  573.      * will be included in the search. I.e excludedRangeInclusive(1,3) will return
  574.      * everything except 1, 2, and 3.
  575.      *
  576.      * <p>
  577.      * if the upper-bound is null the range will be open ended upwards and
  578.      * inclusive.
  579.      * <br>
  580.      * I.e excludedRangeInclusive(1,null) will return ..., -1, 0.
  581.      *
  582.      * <p>
  583.      * if the lower-bound is null the range will be open ended downwards and
  584.      * inclusive.
  585.      * <br>
  586.      * I.e excludedRangeInclusive(null, 5) will return 6, 7, 8, 9, etc.
  587.      *
  588.      * @param lowerBound lowerBound
  589.      * @param upperBound upperBound
  590.      */
  591.     public void excludedRangeInclusive(LocalDateExpression lowerBound, LocalDateExpression upperBound) {
  592.         setOperator(new DBPermittedRangeInclusiveOperator(lowerBound, upperBound));
  593.         negateOperator();
  594.     }

  595.     /**
  596.      * Performs searches based on a range.
  597.      *
  598.      * if both ends of the range are specified both the lower- and upper-bound
  599.      * will be excluded in the search. I.e excludedRangeExclusive(1,3) will return
  600.      * everything except 2.
  601.      *
  602.      * <p>
  603.      * if the upper-bound is null the range will be open ended upwards and
  604.      * exclusive.
  605.      * <br>
  606.      * I.e excludedRangeExclusive(1,null) will return 0, -1, -2, etc.
  607.      *
  608.      * <p>
  609.      * if the lower-bound is null the range will be open ended downwards and
  610.      * exclusive.
  611.      * <br>
  612.      * I.e excludedRangeExclusive(null, 5) will return 5, 6, 7, 8,, etc.
  613.      *
  614.      * @param lowerBound lowerBound
  615.      * @param upperBound upperBound
  616.      */
  617.     public void excludedRangeExclusive(LocalDateExpression lowerBound, LocalDateExpression upperBound) {
  618.         setOperator(new DBPermittedRangeExclusiveOperator(lowerBound, upperBound));
  619.         negateOperator();
  620.     }

  621.     /**
  622.      * Used internally to decide whether the required query needs to include NULL
  623.      * values.
  624.      *
  625.      * <p style="color: #F90;">Support DBvolution at
  626.      * <a href="http://patreon.com/dbvolution" target=new>Patreon</a></p>
  627.      *
  628.      * @return whether the query expression needs to test for NULL.
  629.      */
  630.     @Override
  631.     public boolean getIncludesNull() {
  632.         return localDateValue() == null;
  633.     }

  634.     @Override
  635.     protected void setValueFromStandardStringEncoding(String encodedValue) {
  636.         throw new UnsupportedOperationException("DBLocalDate Does Not Have An Accepted Standard String"); //To change body of generated methods, choose Tools | Templates.
  637.     }

  638.     @Override
  639.     public LocalDateColumn getColumn(RowDefinition row) throws IncorrectRowProviderInstanceSuppliedException {
  640.         return new LocalDateColumn(row, this);
  641.     }

  642.     @Override
  643.     public StringExpression stringResult() {
  644.         return new LocalDateExpression(this).stringResult();
  645.     }

  646.     public void excludeNotNull() {
  647.         this.permittedValues((LocalDate) null);
  648.     }

  649.     public void excludeNull() {
  650.         this.excludedValues((LocalDate) null);
  651.     }

  652.     public void permitOnlyNull() {
  653.         excludeNotNull();
  654.     }

  655.     public void permitOnlyNotNull() {
  656.         excludeNull();
  657.     }

  658.     /**
  659.      * Set the value to be inserted when no value has been set, using
  660.      * {@link #setValue(java.time.LocalDate) setValue(...)}, for the QDT.
  661.      *
  662.      * <p>
  663.      * The value is only used during the initial insert and does not effect the
  664.      * definition of the column within the database.</p>
  665.      *
  666.      * <p>
  667.      * Correct usages for standard date defaults:
  668.      *
  669.      * <pre>
  670.      * &#64;DBColumn
  671.      * public DBDate creationDate = new DBDate().setDefaultInsertValue(LocalDateExpression.currentDate());
  672.      *
  673.      * &#64;DBColumn
  674.      * public DBDate updateDate = new DBDate().setDefaultUpdateValue(LocalDateExpression.currentDate());
  675.      *
  676.      * &#64;DBColumn
  677.      * public DBDate creationOrUpdateDate = new DBDate()
  678.      * .setDefaultInsertValue(LocalDateExpression.currentDate())
  679.      * .setDefaultUpdateValue(LocalDateExpression.currentDate());
  680.      * </pre>
  681.      *
  682.      * @param value the value to use during insertion when no particular value has
  683.      * been specified.
  684.      * @return This QDT
  685.      */
  686.     @Override
  687.     public synchronized DBLocalDate setDefaultInsertValue(LocalDate value) {
  688.         super.setDefaultInsertValue(value);
  689.         return this;
  690.     }

  691.     /**
  692.      * Set the value to be inserted when no value has been set, using
  693.      * {@link #setValue(nz.co.gregs.dbvolution.datatypes.DBLocalDate) setValue(...)},
  694.      * for the QDT.
  695.      *
  696.      * <p>
  697.      * The value is only used during the initial insert and does not effect the
  698.      * definition of the column within the database.</p>
  699.      *
  700.      * <p>
  701.      * Care should be taken when using this as some "obvious" uses are better
  702.      * handled using the
  703.      * {@link #setDefaultInsertValue(nz.co.gregs.dbvolution.results.AnyResult) expression version}.
  704.      * In particular, setDefaultInsertValue(new LocalDate()) is probably NOT what
  705.      * you want, setDefaultInsertValue(LocalDateExpression.currentLocalDate())
  706.      * will produce a correct creation date value.</p>
  707.      *
  708.      * <p>
  709.      * Correct usages for standard date defaults:
  710.      *
  711.      * <pre>
  712.      * &#64;DBColumn
  713.      * public DBLocalDate creationDate = new DBLocalDate().setDefaultInsertValue(LocalDateExpression.currentLocalDate());
  714.      *
  715.      * &#64;DBColumn
  716.      * public DBLocalDate updateDate = new DBLocalDate().setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  717.      *
  718.      * &#64;DBColumn
  719.      * public DBLocalDate creationOrUpdateDate = new DBLocalDate()
  720.      * .setDefaultInsertValue(LocalDateExpression.currentLocalDate())
  721.      * .setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  722.      * </pre>
  723.      *
  724.      * @return This QDT
  725.      */
  726.     public synchronized DBLocalDate setDefaultInsertValueToCurrentLocalDate() {
  727.         super.setDefaultInsertValue(LocalDateExpression.currentLocalDate());
  728.         return this;
  729.     }

  730.     /**
  731.      * Set the value to be inserted when no value has been set, using
  732.      * {@link #setValue(nz.co.gregs.dbvolution.datatypes.DBLocalDate) setValue(...)},
  733.      * for the QDT.
  734.      *
  735.      * <p>
  736.      * The value is only used during the initial insert and does not effect the
  737.      * definition of the column within the database.</p>
  738.      *
  739.      * <p>
  740.      * Care should be taken when using this as some "obvious" uses are better
  741.      * handled using the
  742.      * {@link #setDefaultInsertValue(nz.co.gregs.dbvolution.results.AnyResult) expression version}.
  743.      * In particular, setDefaultInsertValue(new LocalDate()) is probably NOT what
  744.      * you want, setDefaultInsertValue(LocalDateExpression.currentLocalDate())
  745.      * will produce a correct creation date value.</p>
  746.      *
  747.      * <p>
  748.      * Correct usages for standard date defaults:
  749.      *
  750.      * <pre>
  751.      * &#64;DBColumn
  752.      * public DBLocalDate creationDate = new DBLocalDate().setDefaultInsertValue(LocalDateExpression.currentLocalDate());
  753.      *
  754.      * &#64;DBColumn
  755.      * public DBLocalDate updateDate = new DBLocalDate().setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  756.      *
  757.      * &#64;DBColumn
  758.      * public DBLocalDate creationOrUpdateDate = new DBLocalDate()
  759.      * .setDefaultInsertValue(LocalDateExpression.currentLocalDate())
  760.      * .setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  761.      * </pre>
  762.      *
  763.      * @param value the value to use during insertion when no particular value has
  764.      * been specified.
  765.      * @return This QDT
  766.      */
  767.     public synchronized DBLocalDate setDefaultInsertValue(LocalDateResult value) {
  768.         super.setDefaultInsertValue(value);
  769.         return this;
  770.     }

  771.     /**
  772.      * Set the value to be used during an update when no value has been set, using
  773.      * {@link #setValue(java.time.LocalDate)  setValue(...)}, for the QDT.
  774.      *
  775.      * <p>
  776.      * The value is only used during updates and does not effect the definition of
  777.      * the column within the database nor the initial value of the column.</p>
  778.      *
  779.      * <p>
  780.      * Care should be taken when using this as some "obvious" uses are better
  781.      * handled using the
  782.      * {@link #setDefaultUpdateValue(nz.co.gregs.dbvolution.results.AnyResult) expression version}.
  783.      * In particular, setDefaultUpdateValue(new LocalDate()) is probably NOT what
  784.      * you want, setDefaultUpdateValue(LocalDateExpression.currentDate()) will
  785.      * produce a correct update time value.</p>
  786.      *
  787.      * <p>
  788.      * Correct usages for standard date defaults:
  789.      *
  790.      * <pre>
  791.      * &#64;DBColumn
  792.      * public DBLocalDate creationDate = new DBLocalDate().setDefaultInsertValue(LocalDateExpression.currentLocalDate());
  793.      *
  794.      * &#64;DBColumn
  795.      * public DBLocalDate updateDate = new DBLocalDate().setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  796.      *
  797.      * &#64;DBColumn
  798.      * public DBLocalDate creationOrUpdateDate = new DBLocalDate()
  799.      * .setDefaultInsertValue(LocalDateExpression.currentLocalDate())
  800.      * .setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  801.      * </pre>
  802.      *
  803.      * @return This QDT
  804.      */
  805.     public synchronized DBLocalDate setDefaultUpdateValueToCurrentLocalDate() {
  806.         super.setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  807.         return this;
  808.     }

  809.     /**
  810.      * Set the value to be used during an update when no value has been set, using
  811.      * {@link #setValue(java.time.LocalDate)  setValue(...)}, for the QDT.
  812.      *
  813.      * <p>
  814.      * The value is only used during updates and does not effect the definition of
  815.      * the column within the database nor the initial value of the column.</p>
  816.      *
  817.      * <p>
  818.      * Care should be taken when using this as some "obvious" uses are better
  819.      * handled using the
  820.      * {@link #setDefaultUpdateValue(nz.co.gregs.dbvolution.results.AnyResult) expression version}.
  821.      * In particular, setDefaultUpdateValue(new LocalDate()) is probably NOT what
  822.      * you want, setDefaultUpdateValue(LocalDateExpression.currentDate()) will
  823.      * produce a correct update time value.</p>
  824.      *
  825.      * <p>
  826.      * Correct usages for standard date defaults:
  827.      *
  828.      * <pre>
  829.      * &#64;DBColumn
  830.      * public DBLocalDate creationDate = new DBLocalDate().setDefaultInsertValue(LocalDateExpression.currentLocalDate());
  831.      *
  832.      * &#64;DBColumn
  833.      * public DBLocalDate updateDate = new DBLocalDate().setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  834.      *
  835.      * &#64;DBColumn
  836.      * public DBLocalDate creationOrUpdateDate = new DBLocalDate()
  837.      * .setDefaultInsertValue(LocalDateExpression.currentLocalDate())
  838.      * .setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  839.      * </pre>
  840.      *
  841.      * @param value the value to use during update when no particular value has
  842.      * been specified.
  843.      * @return This QDT
  844.      */
  845.     @Override
  846.     public synchronized DBLocalDate setDefaultUpdateValue(LocalDate value) {
  847.         super.setDefaultUpdateValue(value);
  848.         return this;
  849.     }

  850.     /**
  851.      * Set the value to be used during an update when no value has been set, using
  852.      * {@link #setValue(java.time.LocalDate) setValue(...)}, for the QDT.
  853.      *
  854.      * <p>
  855.      * The value is only used during updates and does not effect the definition of
  856.      * the column within the database nor the initial value of the column.</p>
  857.      *
  858.      * <p>
  859.      * Correct usages for standard date defaults:
  860.      *
  861.      * <pre>
  862.      * &#64;DBColumn
  863.      * public DBLocalDate creationDate = new DBLocalDate().setDefaultInsertValue(LocalDateExpression.currentLocalDate());
  864.      *
  865.      * &#64;DBColumn
  866.      * public DBLocalDate updateDate = new DBLocalDate().setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  867.      *
  868.      * &#64;DBColumn
  869.      * public DBLocalDate creationOrUpdateDate = new DBLocalDate()
  870.      * .setDefaultInsertValue(LocalDateExpression.currentLocalDate())
  871.      * .setDefaultUpdateValue(LocalDateExpression.currentLocalDate());
  872.      * </pre>
  873.      *
  874.      * @param value the value to use during update when no particular value has
  875.      * been specified.
  876.      * @return This QDT
  877.      */
  878.     public synchronized DBLocalDate setDefaultUpdateValue(LocalDateResult value) {
  879.         super.setDefaultUpdateValue(value);
  880.         return this;
  881.     }

  882.     public void permitOnlyPastAndPresent() {
  883.         this.setOperator(new DBLessThanOrEqualOperator(LocalDateExpression.currentDate()));
  884.     }

  885.     public void permitOnlyPresentAndFuture() {
  886.         this.setOperator(new DBGreaterThanOrEqualsOperator(LocalDateExpression.currentDate()));
  887.     }

  888.     public void permitOnlyPast() {
  889.         this.setOperator(new DBLessThanOperator(LocalDateExpression.currentDate()));
  890.     }

  891.     public void permitOnlyFuture() {
  892.         this.setOperator(new DBGreaterThanOperator(LocalDateExpression.currentDate()));
  893.     }

  894.     public void permitOnlyPastAndPresentByDateOnly() {
  895.         this.setOperator(new DBLessThanOrEqualOperator(LocalDateExpression.currentDate()));
  896.     }

  897.     public void permitOnlyPresentAndFutureByDateOnly() {
  898.         this.setOperator(new DBGreaterThanOrEqualsOperator(LocalDateExpression.currentLocalDate()));
  899.     }

  900.     public void permitOnlyPastByDateOnly() {
  901.         this.setOperator(new DBLessThanOperator(LocalDateExpression.now()));
  902.     }

  903.     public void permitOnlyFutureByDateOnly() {
  904.         this.setOperator(new DBGreaterThanOperator(LocalDateExpression.today()));
  905.     }

  906.     @Override
  907.     public Comparator<LocalDate> getComparator() {
  908.         return ComparableComparator.forClass(LocalDate.class);
  909.     }
  910. }