All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gate.sql.statement.BasicSentence Maven / Gradle / Ivy

There is a newer version: 12.3.1
Show newest version
package gate.sql.statement;

import gate.error.ConstraintViolationException;
import gate.error.UncheckedConstraintViolationException;
import gate.sql.Command;
import gate.sql.Link;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;

class BasicSentence implements Sentence
{

	private final String sql;

	BasicSentence(String sql)
	{
		this.sql = sql;
	}

	@Override
	public Sentence.Connected connect(Link link)
	{
		return new Connected(link);
	}

	@Override
	public Sentence.Compiled parameters(List parameters)
	{
		return new Compiled(Collections.singletonList(parameters));
	}

	@Override
	public Sentence.Compiled batch(List> parameters)
	{
		return new Compiled(parameters);
	}

	@Override
	public String toString()
	{
		return sql;
	}

	@Override
	public Sentence print()
	{
		System.out.println(toString());
		return this;
	}

	@Override
	public  Extractor from(Class type)
	{
		return new Extractor<>();
	}

	private class Extractor implements Sentence.Extractor
	{

		@Override
		public String toString()
		{
			return sql;
		}

		@Override
		public Compiled parameters(List> extractors)
		{
			return new Compiled(extractors);
		}

		@Override
		public Extractor print()
		{
			System.out.println(toString());
			return this;
		}

		private class Compiled implements Sentence.Extractor.Compiled
		{

			private final List> extractors;

			public Compiled(List> extractors)
			{
				this.extractors = extractors;
			}

			@Override
			public Connected connect(Link link)
			{
				return new Connected(link);
			}

			@Override
			public SQL print()
			{
				System.out.println(toString());
				System.out.println(extractors);
				return this;
			}

			private class Connected implements Sentence.Extractor.Compiled.Connected
			{

				private final Link link;

				private Connected(Link link)
				{
					this.link = link;
				}

				@Override
				public Command createCommand()
				{
					return link.createCommand(sql);
				}

				@Override
				public int execute(List values) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						int count = 0;
						for (T value : values)
						{
							extractors.forEach(e -> command.setParameter(e.apply(value)));
							count += command.execute();
						}
						return count;
					}
				}

				@Override
				public void execute(Stream values) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						values.forEach(value ->
						{
							try
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								command.execute();
							} catch (ConstraintViolationException ex)
							{
								throw new UncheckedConstraintViolationException(ex);
							}
						});
					} catch (UncheckedConstraintViolationException ex)
					{
						throw ex.getCause();
					}
				}

				@Override
				public  void fetchGeneratedKey(List values, Class type, BiConsumer consumer) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						for (T value : values)
						{
							extractors.forEach(e -> command.setParameter(e.apply(value)));
							command.execute(type).ifPresent(e -> consumer.accept(value, e));
						}
					}
				}

				@Override
				public  void fetchGeneratedKey(Stream values, Class type, BiConsumer consumer) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						values.forEach(value ->
						{
							try
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								command.execute(type).ifPresent(e -> consumer.accept(value, e));
							} catch (ConstraintViolationException ex)
							{
								throw new UncheckedConstraintViolationException(ex);
							}
						});
					}
				}

				@Override
				public  void fetchGeneratedKeys(List values, Class type, BiConsumer> consumer) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						for (T value : values)
						{
							extractors.forEach(e -> command.setParameter(e.apply(value)));
							command.execute(type);
							consumer.accept(value, command.getGeneratedKeys(type));
						}
					}
				}

				@Override
				public  void fetchGeneratedKeys(Stream values, Class type, BiConsumer> consumer) throws ConstraintViolationException
				{

					try (Command command = link.createCommand(sql))
					{
						values.forEach(value ->
						{
							try
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								command.execute(type);
								consumer.accept(value, command.getGeneratedKeys(type));
							} catch (ConstraintViolationException ex)
							{
								throw new UncheckedConstraintViolationException(ex);
							}
						});
					}
				}

				@Override
				public Sentence.Extractor.Compiled.Connected observe(Consumer consumer)
				{
					return consumer != null
						? new Observed(consumer) : this;
				}

				@Override
				public Connected print()
				{
					System.out.println(toString());
					System.out.println(extractors);
					return this;
				}

				public class Observed implements Sentence.Extractor.Compiled.Connected
				{

					private final Consumer observer;

					public Observed(Consumer observer)
					{
						this.observer = observer;
					}

					@Override
					public Command createCommand()
					{
						return link.createCommand(sql);
					}

					@Override
					public int execute(List values) throws ConstraintViolationException
					{
						try (Command command = link.createCommand(sql))
						{
							int count = 0;
							for (T value : values)
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								count += command.execute();
								observer.accept(value);
							}
							return count;
						}
					}

					@Override
					public void execute(Stream values) throws ConstraintViolationException
					{
						try (Command command = link.createCommand(sql))
						{
							values.forEach(value ->
							{
								try
								{
									extractors.forEach(e -> command.setParameter(e.apply(value)));
									command.execute();
									observer.accept(value);
								} catch (ConstraintViolationException ex)
								{
									throw new UncheckedConstraintViolationException(ex);
								}
							});
						} catch (UncheckedConstraintViolationException ex)
						{
							throw ex.getCause();
						}
					}

					@Override
					public  void fetchGeneratedKey(List values, Class type, BiConsumer consumer) throws ConstraintViolationException
					{
						try (Command command = link.createCommand(sql))
						{
							for (T value : values)
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								command.execute(type).ifPresent(e -> consumer.accept(value, e));
								observer.accept(value);
							}
						}
					}

					@Override
					public  void fetchGeneratedKey(Stream values, Class type, BiConsumer consumer) throws ConstraintViolationException
					{
						try (Command command = link.createCommand(sql))
						{
							values.forEach(value ->
							{
								try
								{
									extractors.forEach(e -> command.setParameter(e.apply(value)));
									command.execute(type).ifPresent(e -> consumer.accept(value, e));
									observer.accept(value);
								} catch (ConstraintViolationException ex)
								{
									throw new UncheckedConstraintViolationException(ex);
								}
							});
						}
					}

					@Override
					public  void fetchGeneratedKeys(List values, Class type, BiConsumer> consumer) throws ConstraintViolationException
					{
						try (Command command = link.createCommand(sql))
						{
							for (T value : values)
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								command.execute(type);
								consumer.accept(value, command.getGeneratedKeys(type));
								observer.accept(value);
							}
						}
					}

					@Override
					public  void fetchGeneratedKeys(Stream values, Class type, BiConsumer> consumer) throws ConstraintViolationException
					{

						try (Command command = link.createCommand(sql))
						{
							values.forEach(value ->
							{
								try
								{
									extractors.forEach(e -> command.setParameter(e.apply(value)));
									command.execute(type);
									consumer.accept(value, command.getGeneratedKeys(type));
									observer.accept(value);
								} catch (ConstraintViolationException ex)
								{
									throw new UncheckedConstraintViolationException(ex);
								}
							});
						}
					}

					@Override
					public Sentence.Extractor.Compiled.Connected observe(Consumer consumer)
					{
						return Connected.this.observe(consumer);
					}

					@Override
					public String toString()
					{
						return Connected.this.toString();
					}

					@Override
					public Sentence.Extractor.Compiled.Connected print()
					{
						return Connected.this.print();
					}
				}
			}
		}
	}

	private class Connected implements Sentence.Connected
	{

		private final Link link;

		private Connected(Link link)
		{
			this.link = link;
		}

		@Override
		public Sentence.Connected.Compiled parameters(List parameters)
		{
			return new Compiled(Collections.singletonList(parameters));
		}

		@Override
		public Sentence.Connected.Compiled batch(List> batch)
		{
			return new Compiled(batch);
		}

		@Override
		public String toString()
		{
			return sql;
		}

		@Override
		public Sentence.Connected print()
		{
			System.out.println(toString());
			return this;
		}

		@Override
		public  Extractor from(Class type)
		{
			return new Extractor<>();
		}

		@Override
		public Command createCommand()
		{
			return link.createCommand(sql);
		}

		@Override
		public int execute() throws ConstraintViolationException
		{
			return batch(Collections.singletonList(Collections.emptyList())).execute();
		}

		@Override
		public  List fetchGeneratedKeys(Class type) throws ConstraintViolationException
		{
			return parameters(Collections.singletonList(Collections.emptyList())).fetchGeneratedKeys(type);
		}

		@Override
		public  Optional fetchGeneratedKey(Class type) throws ConstraintViolationException
		{
			return parameters(Collections.singletonList(Collections.emptyList())).fetchGeneratedKey(type);
		}

		@Override
		public  void fetchGeneratedKey(Class type, BiConsumer, K> consumer) throws ConstraintViolationException
		{
			parameters(Collections.singletonList(Collections.emptyList())).fetchGeneratedKey(type, consumer);
		}

		@Override
		public  void fetchGeneratedKeys(Class type, BiConsumer, List> consumer) throws ConstraintViolationException
		{
			parameters(Collections.singletonList(Collections.emptyList())).fetchGeneratedKeys(type, consumer);
		}

		private class Compiled implements Sentence.Connected.Compiled
		{

			private final List> batch;

			public Compiled(List> batch)
			{
				this.batch = batch;
			}

			@Override
			public Command createCommand()
			{
				return link.createCommand(sql);
			}

			@Override
			public int execute() throws ConstraintViolationException
			{
				try (Command command = link.createCommand(sql))
				{
					int count = 0;
					for (List parameters : batch)
						count += command.setParameters(parameters).execute();
					return count;
				}
			}

			@Override
			public  List fetchGeneratedKeys(Class type) throws ConstraintViolationException
			{
				try (Command command = link.createCommand(sql))
				{
					if (batch.isEmpty())
						return Collections.emptyList();
					command.setParameters(batch.get(0)).execute();
					return command.getGeneratedKeys(type);
				}
			}

			@Override
			public  Optional fetchGeneratedKey(Class type) throws ConstraintViolationException
			{
				try (Command command = link.createCommand(sql))
				{
					return batch.isEmpty() ? Optional.empty()
						: command.setParameters(batch.get(0)).execute(type);
				}
			}

			@Override
			public  void fetchGeneratedKey(Class type, BiConsumer, K> consumer) throws ConstraintViolationException
			{
				try (Command command = link.createCommand(sql))
				{
					for (List parameters : batch)
						command.setParameters(parameters).execute(type).ifPresent(e -> consumer.accept(parameters, e));
				}
			}

			@Override
			public  void fetchGeneratedKeys(Class type, BiConsumer, List> consumer) throws ConstraintViolationException
			{
				try (Command command = link.createCommand(sql))
				{
					for (List parameters : batch)
					{
						command.setParameters(parameters).execute();
						consumer.accept(parameters, command.getGeneratedKeys(type));
					}
				}
			}

			@Override
			public Sentence.Connected.Compiled observe(Consumer> consumer)
			{
				return consumer != null
					? new Observed(consumer) : this;
			}

			@Override
			public String toString()
			{
				return sql;
			}

			@Override
			public Sentence.Connected.Compiled print()
			{
				System.out.println(toString());
				System.out.println(batch);
				return this;
			}

			private class Observed implements Sentence.Connected.Compiled
			{

				private final Consumer> observer;

				public Observed(Consumer> observer)
				{
					this.observer = observer;
				}

				@Override
				public Command createCommand()
				{
					return link.createCommand(sql);
				}

				@Override
				public int execute() throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						int count = 0;
						for (List parameters : batch)
						{
							count += command.setParameters(parameters).execute();
							observer.accept(parameters);
						}
						return count;
					}
				}

				@Override
				public  Optional fetchGeneratedKey(Class type) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						if (batch.isEmpty())
							return Optional.empty();

						List parameters = batch.get(0);
						Optional key = command.setParameters(parameters).execute(type);
						observer.accept(parameters);
						return key;
					}
				}

				@Override
				public  List fetchGeneratedKeys(Class type) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						if (batch.isEmpty())
							return Collections.emptyList();
						command.setParameters(batch.get(0)).execute();
						return command.getGeneratedKeys(type);
					}
				}

				@Override
				public  void fetchGeneratedKey(Class type, BiConsumer, K> consumer) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						for (List parameters : batch)
						{
							command.setParameters(parameters).execute(type).ifPresent(e -> consumer.accept(parameters, e));
							observer.accept(parameters);
						}
					}
				}

				@Override
				public  void fetchGeneratedKeys(Class type, BiConsumer, List> consumer) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						for (List parameters : batch)
						{
							command.setParameters(parameters).execute();
							consumer.accept(parameters, command.getGeneratedKeys(type));
							observer.accept(parameters);
						}
					}
				}

				@Override
				public Sentence.Connected.Compiled observe(Consumer> consumer)
				{
					return Compiled.this.observe(consumer);
				}

				@Override
				public String toString()
				{
					return Compiled.this.toString();
				}

				@Override
				public Sentence.Connected.Compiled print()
				{
					return Compiled.this.print();
				}
			}
		}

		private class Extractor implements Sentence.Connected.Extractor
		{

			@Override
			public String toString()
			{
				return sql;
			}

			@Override
			public Compiled parameters(List> extractors)
			{
				return new Compiled(extractors);
			}

			@Override
			public Extractor print()
			{
				System.out.println(toString());
				return this;
			}

			public class Compiled implements Sentence.Connected.Extractor.Compiled
			{

				private final List> extractors;

				public Compiled(List> extractors)
				{
					this.extractors = extractors;
				}

				@Override
				public Command createCommand()
				{
					return link.createCommand(sql);
				}

				@Override
				public int execute(List values) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						int count = 0;
						for (T value : values)
						{
							extractors.forEach(e -> command.setParameter(e.apply(value)));
							count += command.execute();
						}
						return count;
					}
				}

				@Override
				public void execute(Stream values) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						values.forEach(value ->
						{
							try
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								command.execute();
							} catch (ConstraintViolationException ex)
							{
								throw new UncheckedConstraintViolationException(ex);
							}
						});
					} catch (UncheckedConstraintViolationException ex)
					{
						throw ex.getCause();
					}
				}

				@Override
				public  void fetchGeneratedKey(List values, Class type, BiConsumer consumer) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						for (T value : values)
						{
							extractors.forEach(e -> command.setParameter(e.apply(value)));
							command.execute(type).ifPresent(e -> consumer.accept(value, e));
						}
					}
				}

				@Override
				public  void fetchGeneratedKey(Stream values, Class type, BiConsumer consumer) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						values.forEach(value ->
						{
							try
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								command.execute(type).ifPresent(e -> consumer.accept(value, e));
							} catch (ConstraintViolationException ex)
							{
								throw new UncheckedConstraintViolationException(ex);
							}
						});
					}
				}

				@Override
				public  void fetchGeneratedKeys(List values, Class type, BiConsumer> consumer) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						for (T value : values)
						{
							extractors.forEach(e -> command.setParameter(e.apply(value)));
							command.execute(type);
							consumer.accept(value, command.getGeneratedKeys(type));
						}
					}
				}

				@Override
				public  void fetchGeneratedKeys(Stream values, Class type, BiConsumer> consumer) throws ConstraintViolationException
				{

					try (Command command = link.createCommand(sql))
					{
						values.forEach(value ->
						{
							try
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								command.execute(type);
								consumer.accept(value, command.getGeneratedKeys(type));
							} catch (ConstraintViolationException ex)
							{
								throw new UncheckedConstraintViolationException(ex);
							}
						});
					}
				}

				@Override
				public Sentence.Connected.Extractor.Compiled observe(Consumer consumer)
				{
					return consumer != null
						? new Observed(consumer) : this;
				}

				@Override
				public Compiled print()
				{
					System.out.println(toString());
					System.out.println(extractors);
					return this;
				}

				public class Observed implements Sentence.Connected.Extractor.Compiled
				{

					private final Consumer observer;

					public Observed(Consumer observer)
					{
						this.observer = observer;
					}

					@Override
					public Command createCommand()
					{
						return link.createCommand(sql);
					}

					@Override
					public int execute(List values) throws ConstraintViolationException
					{
						try (Command command = link.createCommand(sql))
						{
							int count = 0;
							for (T value : values)
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								count += command.execute();
								observer.accept(value);
							}
							return count;
						}
					}

					@Override
					public void execute(Stream values) throws ConstraintViolationException
					{
						try (Command command = link.createCommand(sql))
						{
							values.forEach(value ->
							{
								try
								{
									extractors.forEach(e -> command.setParameter(e.apply(value)));
									command.execute();
									observer.accept(value);
								} catch (ConstraintViolationException ex)
								{
									throw new UncheckedConstraintViolationException(ex);
								}
							});
						} catch (UncheckedConstraintViolationException ex)
						{
							throw ex.getCause();
						}
					}

					@Override
					public  void fetchGeneratedKey(List values, Class type, BiConsumer consumer) throws ConstraintViolationException
					{
						try (Command command = link.createCommand(sql))
						{
							for (T value : values)
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								command.execute(type).ifPresent(e -> consumer.accept(value, e));
								observer.accept(value);
							}
						}
					}

					@Override
					public  void fetchGeneratedKey(Stream values, Class type, BiConsumer consumer) throws ConstraintViolationException
					{
						try (Command command = link.createCommand(sql))
						{
							values.forEach(value ->
							{
								try
								{
									extractors.forEach(e -> command.setParameter(e.apply(value)));
									command.execute(type).ifPresent(e -> consumer.accept(value, e));
									observer.accept(value);
								} catch (ConstraintViolationException ex)
								{
									throw new UncheckedConstraintViolationException(ex);
								}
							});
						}
					}

					@Override
					public  void fetchGeneratedKeys(List values, Class type, BiConsumer> consumer) throws ConstraintViolationException
					{
						try (Command command = link.createCommand(sql))
						{
							for (T value : values)
							{
								extractors.forEach(e -> command.setParameter(e.apply(value)));
								command.execute(type);
								consumer.accept(value, command.getGeneratedKeys(type));
								observer.accept(value);
							}
						}
					}

					@Override
					public  void fetchGeneratedKeys(Stream values, Class type, BiConsumer> consumer) throws ConstraintViolationException
					{

						try (Command command = link.createCommand(sql))
						{
							values.forEach(value ->
							{
								try
								{
									extractors.forEach(e -> command.setParameter(e.apply(value)));
									command.execute(type);
									consumer.accept(value, command.getGeneratedKeys(type));
									observer.accept(value);
								} catch (ConstraintViolationException ex)
								{
									throw new UncheckedConstraintViolationException(ex);
								}
							});
						}
					}

					@Override
					public Sentence.Connected.Extractor.Compiled observe(Consumer consumer)
					{
						return Compiled.this.observe(consumer);
					}

					@Override
					public String toString()
					{
						return Compiled.this.toString();
					}

					@Override
					public Sentence.Connected.Extractor.Compiled print()
					{
						return Compiled.this.print();
					}
				}
			}
		}

	}

	private class Compiled implements Sentence.Compiled
	{

		private final List> batch;

		public Compiled(List> batch)
		{
			this.batch = batch;
		}

		@Override
		public Sentence.Compiled.Connected connect(Link link)
		{
			return new Connected(link);
		}

		@Override
		public String toString()
		{
			return sql;
		}

		@Override
		public Sentence.Compiled print()
		{
			System.out.println(toString());
			System.out.println(batch);
			return this;
		}

		private class Connected implements Sentence.Compiled.Connected
		{

			private final Link link;

			private Connected(Link link)
			{
				this.link = link;
			}

			@Override
			public Command createCommand()
			{
				return link.createCommand(sql);
			}

			@Override
			public int execute() throws ConstraintViolationException
			{
				try (Command command = link.createCommand(sql))
				{
					int count = 0;
					for (List parameters : batch)
						count += command.setParameters(parameters).execute();
					return count;
				}
			}

			@Override
			public  Optional fetchGeneratedKey(Class type) throws ConstraintViolationException
			{
				try (Command command = link.createCommand(sql))
				{
					return batch.isEmpty() ? Optional.empty()
						: command.setParameters(batch.get(0)).execute(type);
				}
			}

			@Override
			public  List fetchGeneratedKeys(Class type) throws ConstraintViolationException
			{
				try (Command command = link.createCommand(sql))
				{
					if (batch.isEmpty())
						return Collections.emptyList();
					command.setParameters(batch.get(0)).execute();
					return command.getGeneratedKeys(type);
				}
			}

			@Override
			public  void fetchGeneratedKey(Class type, BiConsumer, T> consumer) throws ConstraintViolationException
			{
				try (Command command = link.createCommand(sql))
				{
					for (List parameters : batch)
						command.setParameters(parameters).execute(type).ifPresent(e -> consumer.accept(parameters, e));
				}
			}

			@Override
			public  void fetchGeneratedKeys(Class type, BiConsumer, List> consumer) throws ConstraintViolationException
			{
				try (Command command = link.createCommand(sql))
				{
					for (List parameters : batch)
					{
						command.setParameters(parameters).execute();
						consumer.accept(parameters, command.getGeneratedKeys(type));
					}
				}
			}

			@Override
			public Sentence.Compiled.Connected observe(Consumer> consumer)
			{
				return consumer != null
					? new Observed(consumer) : this;
			}

			@Override
			public String toString()
			{
				return sql;
			}

			@Override
			public Sentence.Compiled.Connected print()
			{
				System.out.println(toString());
				System.out.println(batch);
				return this;
			}

			private class Observed implements Sentence.Compiled.Connected
			{

				private final Consumer> observer;

				public Observed(Consumer> observer)
				{
					this.observer = observer;
				}

				@Override
				public Command createCommand()
				{
					return link.createCommand(sql);
				}

				@Override
				public int execute() throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						int count = 0;
						for (List parameters : batch)
						{
							count += command.setParameters(parameters).execute();
							observer.accept(parameters);
						}
						return count;
					}
				}

				@Override
				public  Optional fetchGeneratedKey(Class type) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						if (batch.isEmpty())
							return Optional.empty();

						List parameters = batch.get(0);
						Optional key = command.setParameters(parameters).execute(type);
						observer.accept(parameters);
						return key;
					}
				}

				@Override
				public  List fetchGeneratedKeys(Class type) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						if (batch.isEmpty())
							return Collections.emptyList();
						List parameters = batch.get(0);
						command.setParameters(batch.get(0)).execute();
						observer.accept(parameters);
						return command.getGeneratedKeys(type);
					}
				}

				@Override
				public  void fetchGeneratedKey(Class type, BiConsumer, T> consumer) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						for (List parameters : batch)
						{
							command.setParameters(parameters).execute(type).ifPresent(e -> consumer.accept(parameters, e));
							observer.accept(parameters);
						}
					}
				}

				@Override
				public  void fetchGeneratedKeys(Class type, BiConsumer, List> consumer) throws ConstraintViolationException
				{
					try (Command command = link.createCommand(sql))
					{
						for (List parameters : batch)
						{
							command.setParameters(parameters).execute();
							consumer.accept(parameters, command.getGeneratedKeys(type));
							observer.accept(parameters);
						}
					}
				}

				@Override
				public Sentence.Compiled.Connected observe(Consumer> consumer)
				{
					return Connected.this.observe(consumer);
				}

				@Override
				public String toString()
				{
					return Connected.this.toString();
				}

				@Override
				public Sentence.Compiled.Connected print()
				{
					return Connected.this.print();
				}
			}
		}
	}
}