├── ruby ├── rails │ └── petclinic │ │ ├── log │ │ └── .keep │ │ ├── tmp │ │ ├── .keep │ │ ├── pids │ │ │ └── .keep │ │ └── storage │ │ │ └── .keep │ │ ├── vendor │ │ ├── .keep │ │ └── javascript │ │ │ └── .keep │ │ ├── lib │ │ ├── assets │ │ │ └── .keep │ │ └── tasks │ │ │ └── .keep │ │ ├── storage │ │ └── .keep │ │ ├── test │ │ ├── models │ │ │ ├── .keep │ │ │ ├── owner_test.rb │ │ │ ├── pet_test.rb │ │ │ ├── vet_test.rb │ │ │ ├── specialty_test.rb │ │ │ └── vet_specialty_test.rb │ │ ├── system │ │ │ └── .keep │ │ ├── controllers │ │ │ ├── .keep │ │ │ ├── pets_controller_test.rb │ │ │ ├── vets_controller_test.rb │ │ │ ├── owners_controller_test.rb │ │ │ ├── specialties_controller_test.rb │ │ │ └── vet_specialties_controller_test.rb │ │ ├── helpers │ │ │ └── .keep │ │ ├── integration │ │ │ └── .keep │ │ ├── mailers │ │ │ └── .keep │ │ ├── fixtures │ │ │ ├── files │ │ │ │ └── .keep │ │ │ ├── vets.yml │ │ │ ├── specialties.yml │ │ │ ├── vet_specialties.yml │ │ │ ├── pets.yml │ │ │ └── owners.yml │ │ ├── application_system_test_case.rb │ │ ├── channels │ │ │ └── application_cable │ │ │ │ └── connection_test.rb │ │ └── test_helper.rb │ │ ├── app │ │ ├── assets │ │ │ ├── images │ │ │ │ └── .keep │ │ │ ├── config │ │ │ │ └── manifest.js │ │ │ └── stylesheets │ │ │ │ └── application.css │ │ ├── models │ │ │ ├── concerns │ │ │ │ └── .keep │ │ │ ├── application_record.rb │ │ │ ├── vet_specialty.rb │ │ │ ├── pet.rb │ │ │ ├── specialty.rb │ │ │ ├── vet.rb │ │ │ └── owner.rb │ │ ├── controllers │ │ │ ├── concerns │ │ │ │ └── .keep │ │ │ ├── pets_controller.rb │ │ │ ├── vets_controller.rb │ │ │ ├── specialties_controller.rb │ │ │ ├── application_controller.rb │ │ │ ├── vet_specialties_controller.rb │ │ │ └── owners_controller.rb │ │ ├── views │ │ │ ├── layouts │ │ │ │ ├── mailer.text.erb │ │ │ │ ├── mailer.html.erb │ │ │ │ └── application.html.erb │ │ │ ├── owners │ │ │ │ ├── index.html.erb │ │ │ │ └── show.html.erb │ │ │ ├── pets │ │ │ │ ├── index.html.erb │ │ │ │ └── show.html.erb │ │ │ ├── vets │ │ │ │ ├── index.html.erb │ │ │ │ └── show.html.erb │ │ │ └── pwa │ │ │ │ ├── manifest.json.erb │ │ │ │ └── service-worker.js │ │ ├── helpers │ │ │ ├── pets_helper.rb │ │ │ ├── vets_helper.rb │ │ │ ├── owners_helper.rb │ │ │ ├── application_helper.rb │ │ │ ├── specialties_helper.rb │ │ │ └── vet_specialties_helper.rb │ │ ├── channels │ │ │ └── application_cable │ │ │ │ ├── channel.rb │ │ │ │ └── connection.rb │ │ ├── mailers │ │ │ └── application_mailer.rb │ │ ├── javascript │ │ │ ├── application.js │ │ │ └── controllers │ │ │ │ ├── hello_controller.js │ │ │ │ ├── application.js │ │ │ │ └── index.js │ │ └── jobs │ │ │ └── application_job.rb │ │ ├── .ruby-version │ │ ├── bin │ │ ├── rake │ │ ├── importmap │ │ ├── rails │ │ ├── brakeman │ │ ├── rubocop │ │ ├── docker-entrypoint │ │ └── setup │ │ ├── public │ │ ├── icon.png │ │ ├── robots.txt │ │ ├── icon.svg │ │ ├── 406-unsupported-browser.html │ │ ├── 500.html │ │ ├── 422.html │ │ └── 404.html │ │ ├── config │ │ ├── environment.rb │ │ ├── boot.rb │ │ ├── cable.yml │ │ ├── importmap.rb │ │ ├── credentials.yml.enc │ │ ├── initializers │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── permissions_policy.rb │ │ │ ├── assets.rb │ │ │ ├── inflections.rb │ │ │ ├── content_security_policy.rb │ │ │ └── adapter.rb │ │ ├── routes.rb │ │ ├── locales │ │ │ └── en.yml │ │ ├── application.rb │ │ ├── storage.yml │ │ └── puma.rb │ │ ├── config.ru │ │ ├── Rakefile │ │ ├── db │ │ ├── migrate │ │ │ ├── 20241107085643_create_specialties.rb │ │ │ ├── 20241031171244_create_vets.rb │ │ │ ├── 20241107085734_create_vet_specialties.rb │ │ │ ├── 20241031171030_create_pets.rb │ │ │ └── 20241031170806_create_owners.rb │ │ └── seeds.rb │ │ ├── .rubocop.yml │ │ ├── .github │ │ └── dependabot.yml │ │ ├── .gitattributes │ │ ├── .gitignore │ │ └── .dockerignore ├── cluster_management │ ├── Gemfile │ ├── Rakefile │ └── lib │ │ ├── get_cluster.rb │ │ ├── update_cluster.rb │ │ ├── delete_single_region_cluster.rb │ │ ├── create_single_region_cluster.rb │ │ └── delete_multi_region_clusters.rb └── ruby-pg │ ├── Rakefile │ ├── Gemfile │ └── spec │ └── smoke_spec.rb ├── lambda ├── .gitignore ├── package.json ├── sample │ └── package.json └── cdk.js ├── typescript ├── sequelize │ ├── .gitignore │ ├── test │ │ └── index.spec.ts │ ├── tsconfig.json │ └── package.json ├── prisma │ ├── .gitignore │ ├── .prettierrc │ ├── jest.config.js │ ├── src │ │ ├── utils.ts │ │ ├── index.ts │ │ └── veterinary-service.ts │ ├── prisma │ │ ├── migrations │ │ │ └── 0_init │ │ │ │ ├── down.sql │ │ │ │ └── migration.sql │ │ └── veterinary-schema.prisma │ ├── tsconfig.json │ └── package.json └── type-orm │ ├── .gitignore │ ├── test │ └── index.spec.ts │ ├── tsconfig.json │ ├── src │ ├── entity │ │ ├── Specialty.ts │ │ ├── VetSpecialty.ts │ │ ├── Owner.ts │ │ ├── Pet.ts │ │ └── Vet.ts │ ├── utils.ts │ ├── drop-migrations-table.ts │ ├── data-source.ts │ ├── migrations │ │ └── 1731957649222-BaseMigration.ts │ └── create-migrations-table.ts │ └── package.json ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── feature-request.md ├── PULL_REQUEST_TEMPLATE.yml ├── workflows │ ├── deps-review.yml │ ├── gitleaks-scan.yml │ ├── close-issue-message.yml │ ├── clean-clusters.yml │ ├── go-pgx-integ-tests.yml │ ├── rust-sqlx-integ-test.yml │ ├── dotnet-npgsql-integ-tests.yml │ ├── ruby-pg-integ-tests.yml │ ├── typescript-sequelize-integ-tests.yml │ ├── javascript-node-postgres-integ-tests.yml │ ├── java-pgjdbc-integ-tests.yml │ ├── javascript-postgresjs-integ-tests.yml │ ├── java-pgjdbc-hikaricp-integ-tests.yml │ └── typescript-type-orm-integ-tests.yml └── depandabot.yml ├── NOTICE ├── java ├── spring_boot │ ├── settings.gradle.kts │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── build.gradle.kts │ ├── src │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── example │ │ │ │ ├── ApiController.java │ │ │ │ ├── DataSourceConfig.java │ │ │ │ ├── DatabaseService.java │ │ │ │ └── Application.java │ │ │ └── resources │ │ │ └── application.yml │ └── pom.xml ├── pgjdbc │ ├── settings.gradle.kts │ ├── src │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── example │ │ │ └── DsqlExampleTest.java │ └── build.gradle.kts ├── pgjdbc_hikaricp │ ├── settings.gradle.kts │ ├── src │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── example │ │ │ └── DsqlHikariCPExampleTest.java │ └── build.gradle.kts ├── .gitignore ├── cluster_management │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── example │ │ ├── GetCluster.java │ │ ├── UpdateCluster.java │ │ └── DeleteCluster.java └── liquibase │ └── pom.xml ├── javascript ├── node-postgres │ ├── .gitignore │ ├── test │ │ └── smoke.test.js │ └── package.json ├── postgres-js │ ├── .gitignore │ ├── test │ │ └── smoke.test.js │ └── package.json └── cluster_management │ ├── package.json │ └── src │ ├── get_cluster.js │ ├── update_cluster.js │ ├── create_single_region_cluster.js │ └── delete_single_region_cluster.js ├── python ├── psycopg │ ├── requirements.txt │ ├── pyproject.toml │ └── test │ │ └── test_example.py ├── cluster_management │ ├── requirements.txt │ ├── pyproject.toml │ └── src │ │ ├── get_cluster.py │ │ ├── update_cluster.py │ │ ├── delete_single_region.py │ │ ├── create_single_region.py │ │ └── delete_multi_region.py ├── psycopg2 │ ├── requirements.txt │ ├── pyproject.toml │ └── test │ │ └── test_example.py └── sqlalchemy │ ├── pyproject.toml │ ├── requirements.txt │ ├── test │ └── test_example.py │ └── setup.sh ├── cpp ├── cluster_management │ └── src │ │ ├── CreateSingleRegion.h │ │ ├── DeleteSingleRegion.h │ │ ├── GetCluster.h │ │ ├── UpdateCluster.h │ │ ├── DeleteMultiRegion.h │ │ └── CreateMultiRegion.h └── libpq │ └── src │ └── Makefile ├── CODE_OF_CONDUCT.md ├── go ├── .gitignore ├── cluster_management │ ├── go.mod │ ├── internal │ │ └── util │ │ │ ├── disable_delete_protect.go │ │ │ └── find_cluster.go │ ├── Makefile │ ├── cmd │ │ ├── create_single_region │ │ │ └── create_single_region_integ_test.go │ │ ├── create_multi_region │ │ │ └── create_multi_region_integ_test.go │ │ ├── get_cluster │ │ │ ├── get_cluster_integ.go │ │ │ └── get_cluster_integ_test.go │ │ ├── update_cluster │ │ │ └── update_cluster.go │ │ └── delete_single_region │ │ │ └── delete_single_cluster_integ_test.go │ └── README.md └── pgx │ └── go.mod ├── rust ├── sqlx │ └── Cargo.toml ├── cluster_management │ ├── src │ │ ├── lib.rs │ │ └── bin │ │ │ ├── get_cluster.rs │ │ │ └── update_cluster.rs │ ├── Cargo.toml │ └── tests │ │ └── single_region_test.rs └── .gitignore ├── quickstart_data └── department-insert-multirow.sql ├── dotnet ├── npgsql │ └── example.csproj └── cluster_management │ ├── examples │ ├── GetCluster │ │ ├── GetCluster.csproj │ │ └── GetCluster.cs │ ├── UpdateCluster │ │ ├── UpdateCluster.csproj │ │ └── UpdateCluster.cs │ ├── CreateMultiRegionClusters │ │ └── CreateMultiRegionClusters.csproj │ ├── CreateSingleRegionCluster │ │ ├── CreateSingleRegionCluster.csproj │ │ └── CreateSingleRegionCluster.cs │ ├── DeleteMultiRegionClusters │ │ └── DeleteMultiRegionClusters.csproj │ └── DeleteSingleRegionCluster │ │ ├── DeleteSingleRegionCluster.csproj │ │ └── DeleteSingleRegionCluster.cs │ └── tests │ └── DsqlExamples.Tests.csproj ├── LICENSE └── .gitignore /ruby/rails/petclinic/log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/tmp/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/vendor/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lambda/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/storage/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/system/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/tmp/pids/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/tmp/storage/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/controllers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/helpers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/integration/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/fixtures/files/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/vendor/javascript/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-3.3.5 2 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /typescript/sequelize/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | blank_issues_enabled: true 3 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /typescript/prisma/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | generated/ 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/helpers/pets_helper.rb: -------------------------------------------------------------------------------- 1 | module PetsHelper 2 | end 3 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/helpers/vets_helper.rb: -------------------------------------------------------------------------------- 1 | module VetsHelper 2 | end 3 | -------------------------------------------------------------------------------- /java/spring_boot/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "DSQLSpringBootExample" 2 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/helpers/owners_helper.rb: -------------------------------------------------------------------------------- 1 | module OwnersHelper 2 | end 3 | -------------------------------------------------------------------------------- /typescript/type-orm/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /build 3 | /dist 4 | /coverage 5 | -------------------------------------------------------------------------------- /java/pgjdbc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "DSQLPGJDBCPetClinicExample" 2 | 3 | -------------------------------------------------------------------------------- /javascript/node-postgres/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /build 3 | /dist 4 | /coverage 5 | -------------------------------------------------------------------------------- /javascript/postgres-js/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /build 3 | /dist 4 | /coverage 5 | -------------------------------------------------------------------------------- /python/psycopg/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3>=1.35.74 2 | psycopg[binary]>=3 3 | pytest>=8 4 | -------------------------------------------------------------------------------- /java/pgjdbc_hikaricp/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "DSQLPGJDBCHikariCPExample" 2 | -------------------------------------------------------------------------------- /python/cluster_management/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3>=1.38.15 2 | botocore>=1.38.15 3 | pytest>=8 -------------------------------------------------------------------------------- /python/psycopg2/requirements.txt: -------------------------------------------------------------------------------- 1 | boto3>=1.35.74 2 | psycopg2-binary>=2.9 3 | pytest>=8 4 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/helpers/specialties_helper.rb: -------------------------------------------------------------------------------- 1 | module SpecialtiesHelper 2 | end 3 | -------------------------------------------------------------------------------- /python/psycopg/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.pytest.ini_options] 2 | pythonpath = [ 3 | "src" 4 | ] 5 | -------------------------------------------------------------------------------- /python/psycopg2/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.pytest.ini_options] 2 | pythonpath = [ 3 | "src" 4 | ] 5 | -------------------------------------------------------------------------------- /python/sqlalchemy/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.pytest.ini_options] 2 | pythonpath = [ 3 | "src" 4 | ] -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/helpers/vet_specialties_helper.rb: -------------------------------------------------------------------------------- 1 | module VetSpecialtiesHelper 2 | end 3 | -------------------------------------------------------------------------------- /python/cluster_management/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.pytest.ini_options] 2 | pythonpath = [ 3 | "src" 4 | ] -------------------------------------------------------------------------------- /python/sqlalchemy/requirements.txt: -------------------------------------------------------------------------------- 1 | sqlalchemy 2 | psycopg2-binary>=2.9 3 | pytest>=8 4 | boto3>=1.35.74 5 | -------------------------------------------------------------------------------- /ruby/cluster_management/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "aws-sdk-dsql", "~> 1.8" 4 | gem 'rspec', '3.13.0' -------------------------------------------------------------------------------- /ruby/rails/petclinic/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | primary_abstract_class 3 | end 4 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/bin/importmap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative "../config/application" 4 | require "importmap/commands" 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aurora-dsql-samples/HEAD/ruby/rails/petclinic/public/icon.png -------------------------------------------------------------------------------- /ruby/rails/petclinic/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/models/vet_specialty.rb: -------------------------------------------------------------------------------- 1 | class VetSpecialty < ApplicationRecord 2 | belongs_to :vet 3 | belongs_to :specialty 4 | end 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /ruby/ruby-pg/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rspec/core/rake_task' 2 | 3 | desc "Run unit tests in spec/" 4 | RSpec::Core::RakeTask.new(:spec) 5 | task :test => :spec 6 | -------------------------------------------------------------------------------- /ruby/cluster_management/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rspec/core/rake_task' 2 | 3 | desc "Run unit tests in spec/" 4 | RSpec::Core::RakeTask.new(:spec) 5 | task :test => :spec -------------------------------------------------------------------------------- /cpp/cluster_management/src/CreateSingleRegion.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | Aws::DSQL::Model::CreateClusterResult CreateCluster(const Aws::String& region); 4 | -------------------------------------------------------------------------------- /cpp/cluster_management/src/DeleteSingleRegion.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void DeleteCluster(const Aws::String& region, const Aws::String& identifier); 4 | -------------------------------------------------------------------------------- /java/spring_boot/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aurora-dsql-samples/HEAD/java/spring_boot/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /javascript/postgres-js/test/smoke.test.js: -------------------------------------------------------------------------------- 1 | import { example } from '../src/index.js'; 2 | 3 | test('Smoke test', async () => { 4 | await example(); 5 | }, 20000); 6 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: "from@example.com" 3 | layout "mailer" 4 | end 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/public/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /typescript/prisma/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "singleQuote": false, 5 | "printWidth": 80, 6 | "tabWidth": 4 7 | } 8 | -------------------------------------------------------------------------------- /ruby/ruby-pg/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gem 'pg', '1.5.9' 6 | gem 'rspec', '3.13.0' 7 | gem 'aws-sdk-dsql', '~> 1.6' 8 | -------------------------------------------------------------------------------- /cpp/cluster_management/src/GetCluster.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | Aws::DSQL::Model::GetClusterResult GetCluster(const Aws::String& region, const Aws::String& identifier); 4 | 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.yml: -------------------------------------------------------------------------------- 1 | By submitting this pull request, I confirm that my contribution is made under 2 | the terms of the MIT-0 license. 3 | 4 | Thank you for your contribution! -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/models/owner_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class OwnerTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/models/pet_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class PetTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/models/vet_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class VetTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /javascript/node-postgres/test/smoke.test.js: -------------------------------------------------------------------------------- 1 | import { example } from '../src/index.js'; 2 | 3 | test('Smoke test', async () => { 4 | await example(); 5 | return Promise.resolve(); 6 | }); 7 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/bin/brakeman: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | ARGV.unshift("--ensure-latest") 6 | 7 | load Gem.bin_path("brakeman", "brakeman") 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/models/specialty_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class SpecialtyTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/fixtures/vets.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | name: MyString 5 | 6 | two: 7 | name: MyString 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/models/vet_specialty_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class VetSpecialtyTest < ActiveSupport::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | //= link_tree ../../javascript .js 4 | //= link_tree ../../../vendor/javascript .js 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/fixtures/specialties.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | name: MyString 5 | 6 | two: 7 | name: MyString 8 | -------------------------------------------------------------------------------- /cpp/cluster_management/src/UpdateCluster.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | Aws::DSQL::Model::UpdateClusterResult UpdateCluster(const Aws::String& region, const Aws::Map& updateParams); 4 | 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/javascript/application.js: -------------------------------------------------------------------------------- 1 | // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails 2 | import "@hotwired/turbo-rails" 3 | import "controllers" 4 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/controllers/pets_controller_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class PetsControllerTest < ActionDispatch::IntegrationTest 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/controllers/vets_controller_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class VetsControllerTest < ActionDispatch::IntegrationTest 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /cpp/cluster_management/src/DeleteMultiRegion.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void DeleteMultiRegionClusters(const Aws::String& region1, const Aws::String& clusterId1, const Aws::String& region2, const Aws::String& clusterId2); -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/controllers/owners_controller_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class OwnersControllerTest < ActionDispatch::IntegrationTest 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/controllers/pets_controller.rb: -------------------------------------------------------------------------------- 1 | class PetsController < ApplicationController 2 | def index 3 | @pets = Pet.all 4 | end 5 | 6 | def show 7 | @pet = Pet.find(params[:id]) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/controllers/vets_controller.rb: -------------------------------------------------------------------------------- 1 | class VetsController < ApplicationController 2 | def index 3 | @vets = Vet.all 4 | end 5 | 6 | def show 7 | @vet = Vet.find(params[:id]) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/controllers/specialties_controller_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class SpecialtiesControllerTest < ActionDispatch::IntegrationTest 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /ruby/ruby-pg/spec/smoke_spec.rb: -------------------------------------------------------------------------------- 1 | require 'hello_dsql' 2 | 3 | describe 'perform smoke tests' do 4 | it 'does not raise any exception' do 5 | expect { 6 | main() 7 | }.not_to raise_error 8 | end 9 | end -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 4 | driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ] 5 | end 6 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/controllers/vet_specialties_controller_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class VetSpecialtiesControllerTest < ActionDispatch::IntegrationTest 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/javascript/controllers/hello_controller.js: -------------------------------------------------------------------------------- 1 | import { Controller } from "@hotwired/stimulus" 2 | 3 | export default class extends Controller { 4 | connect() { 5 | this.element.textContent = "Hello World!" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/fixtures/vet_specialties.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | vet_id: 5 | specialty_id: 6 | 7 | two: 8 | vet_id: 9 | specialty_id: 10 | -------------------------------------------------------------------------------- /lambda/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dsql_lambda_js_howto", 3 | "version": "1.0.0", 4 | "description": "How To", 5 | "type": "module", 6 | "scripts": { 7 | "cdk": "cdk" 8 | }, 9 | "dependencies": { 10 | "aws-cdk-lib": "^2.200.1" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/controllers/specialties_controller.rb: -------------------------------------------------------------------------------- 1 | class SpecialtiesController < ApplicationController 2 | def index 3 | @specialties = Specialty.all 4 | end 5 | 6 | def show 7 | @specialty = Specialty.find(params[:id]) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: petclinic_production 11 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/fixtures/pets.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | name: MyString 5 | birth_date: 2024-10-31 6 | 7 | two: 8 | name: MyString 9 | birth_date: 2024-10-31 10 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative "config/application" 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. 3 | allow_browser versions: :modern 4 | end 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/owners/index.html.erb: -------------------------------------------------------------------------------- 1 |

Owners

2 | 3 |
    4 | <% @owners.each do |o| %> 5 |
  • 6 | <%= link_to o.name, o %> 7 |
  • 8 | <% end %> 9 |
10 | 11 | <%= link_to "Pets", "/pets" %> 12 | <%= link_to "Vets", "/vets" %> -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/pets/index.html.erb: -------------------------------------------------------------------------------- 1 |

Pets

2 | 3 |
    4 | <% @pets.each do |p| %> 5 |
  • 6 | <%= link_to p.name, p %> 7 |
  • 8 | <% end %> 9 |
10 | 11 | <%= link_to "Owners", "/owners" %> 12 | <%= link_to "Vets", "/vets" %> -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/vets/index.html.erb: -------------------------------------------------------------------------------- 1 |

Vets

2 | 3 |
    4 | <% @vets.each do |v| %> 5 |
  • 6 | <%= link_to v.name, v %> 7 |
  • 8 | <% end %> 9 |
10 | 11 | <%= link_to "Owners", "/owners" %> 12 | <%= link_to "Pets", "/pets" %> -------------------------------------------------------------------------------- /ruby/rails/petclinic/db/migrate/20241107085643_create_specialties.rb: -------------------------------------------------------------------------------- 1 | class CreateSpecialties < ActiveRecord::Migration[7.2] 2 | def change 3 | create_table :specialties, id: :uuid do |t| 4 | t.string :name 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /typescript/sequelize/test/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { runExamples } from "../src/index.js" 2 | 3 | const SECONDS = 1000; 4 | 5 | describe("Index module", () => { 6 | test("Runs all the example code", async () => { 7 | await runExamples(); 8 | }, 60 * SECONDS) 9 | }) 10 | -------------------------------------------------------------------------------- /python/psycopg/test/test_example.py: -------------------------------------------------------------------------------- 1 | from example import main 2 | 3 | import pytest 4 | 5 | 6 | # Smoke tests that our example works fine 7 | def test_example(): 8 | try: 9 | main() 10 | except Exception as e: 11 | pytest.fail(f"Unexpected exception: {e}") 12 | -------------------------------------------------------------------------------- /python/psycopg2/test/test_example.py: -------------------------------------------------------------------------------- 1 | from example import main 2 | 3 | import pytest 4 | 5 | 6 | # Smoke tests that our example works fine 7 | def test_example(): 8 | try: 9 | main() 10 | except Exception as e: 11 | pytest.fail(f"Unexpected exception: {e}") 12 | -------------------------------------------------------------------------------- /typescript/type-orm/test/index.spec.ts: -------------------------------------------------------------------------------- 1 | 2 | import { runExamples } from "../src/index" 3 | 4 | const SECONDS = 1000; 5 | 6 | describe("Index module", () => { 7 | test("Runs all the example code", async () => { 8 | await runExamples(); 9 | }, 60 * SECONDS) 10 | }) 11 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/controllers/vet_specialties_controller.rb: -------------------------------------------------------------------------------- 1 | class VetSpecialtiesController < ApplicationController 2 | def index 3 | @vetspecialties = VetSpecialties.all 4 | end 5 | 6 | def show 7 | @vetspecialty = VetSpecialties.find(params[:id]) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/db/migrate/20241031171244_create_vets.rb: -------------------------------------------------------------------------------- 1 | class CreateVets < ActiveRecord::Migration[7.2] 2 | def change 3 | create_table :vets, id: :uuid do |t| 4 | t.string :name, limit: 30 5 | t.uuid :owner_id 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /cpp/cluster_management/src/CreateMultiRegion.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | std::pair CreateMultiRegionClusters( 4 | const Aws::String& region1, 5 | const Aws::String& region2, 6 | const Aws::String& witnessRegion); 7 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/.rubocop.yml: -------------------------------------------------------------------------------- 1 | # Omakase Ruby styling for Rails 2 | inherit_gem: { rubocop-rails-omakase: rubocop.yml } 3 | 4 | # Overwrite or add rules to create your own house style 5 | # 6 | # # Use `[a, [b, c]]` not `[ a, [ b, c ] ]` 7 | # Layout/SpaceInsideArrayLiteralBrackets: 8 | # Enabled: false 9 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/fixtures/owners.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | 3 | one: 4 | name: MyString 5 | city: MyString 6 | telephone: MyString 7 | 8 | two: 9 | name: MyString 10 | city: MyString 11 | telephone: MyString 12 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/javascript/controllers/application.js: -------------------------------------------------------------------------------- 1 | import { Application } from "@hotwired/stimulus" 2 | 3 | const application = Application.start() 4 | 5 | // Configure Stimulus development experience 6 | application.debug = false 7 | window.Stimulus = application 8 | 9 | export { application } 10 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/bin/rubocop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | # explicit rubocop config increases performance slightly while avoiding config confusion. 6 | ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) 7 | 8 | load Gem.bin_path("rubocop", "rubocop") 9 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/db/migrate/20241107085734_create_vet_specialties.rb: -------------------------------------------------------------------------------- 1 | class CreateVetSpecialties < ActiveRecord::Migration[7.2] 2 | def change 3 | create_table :vet_specialties, id: :uuid do |t| 4 | t.uuid :vet_id 5 | t.uuid :specialty_id 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /java/spring_boot/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/db/migrate/20241031171030_create_pets.rb: -------------------------------------------------------------------------------- 1 | class CreatePets < ActiveRecord::Migration[7.2] 2 | def change 3 | create_table :pets, id: :uuid do |t| 4 | t.string :name, limit: 30 5 | t.date :birth_date 6 | t.uuid :owner_id 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /lambda/sample/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dsql-lambda-sample", 3 | "version": "1.0.0", 4 | "description": "Lambda function for Aurora DSQL", 5 | "main": "lambda.mjs", 6 | "type": "module", 7 | "dependencies": { 8 | "@aws-sdk/dsql-signer": "^3.705.0", 9 | "pg": "^8.13.1", 10 | "assert": "2.1.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /python/sqlalchemy/test/test_example.py: -------------------------------------------------------------------------------- 1 | from example import example, run_retry 2 | import pytest 3 | import os 4 | 5 | # Smoke tests that our example works fine 6 | def test_example(): 7 | try: 8 | example() 9 | run_retry() 10 | except Exception as e: 11 | pytest.fail(f"Unexpected exception: {e}") 12 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/javascript/controllers/index.js: -------------------------------------------------------------------------------- 1 | // Import and register all your controllers from the importmap via controllers/**/*_controller 2 | import { application } from "controllers/application" 3 | import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" 4 | eagerLoadControllersFrom("controllers", application) 5 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /typescript/type-orm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "node16", 5 | "moduleResolution": "node16", 6 | "experimentalDecorators": true, 7 | "emitDecoratorMetadata": true, 8 | "outDir": "dist", 9 | }, 10 | "include": ["./src/**/*", "./test/**/*"] 11 | } -------------------------------------------------------------------------------- /ruby/rails/petclinic/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: bundler 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | - package-ecosystem: github-actions 9 | directory: "/" 10 | schedule: 11 | interval: daily 12 | open-pull-requests-limit: 10 13 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/importmap.rb: -------------------------------------------------------------------------------- 1 | # Pin npm packages by running ./bin/importmap 2 | 3 | pin "application" 4 | pin "@hotwired/turbo-rails", to: "turbo.min.js" 5 | pin "@hotwired/stimulus", to: "stimulus.min.js" 6 | pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" 7 | pin_all_from "app/javascript/controllers", under: "controllers" 8 | -------------------------------------------------------------------------------- /java/pgjdbc/src/test/java/org/example/DsqlExampleTest.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | public class DsqlExampleTest { 8 | @Test 9 | public void testExample() { 10 | assertAll(() -> Example.main(new String[]{})); 11 | } 12 | } -------------------------------------------------------------------------------- /typescript/sequelize/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "node16", 5 | "moduleResolution": "node16", 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "outDir": "dist", 10 | }, 11 | "include" : ["src/**/*", "test/**/*"] 12 | } -------------------------------------------------------------------------------- /ruby/rails/petclinic/db/migrate/20241031170806_create_owners.rb: -------------------------------------------------------------------------------- 1 | class CreateOwners < ActiveRecord::Migration[7.2] 2 | def change 3 | create_table :owners, id: :uuid do |t| 4 | t.string :name, limit: 30 5 | t.string :city, limit: 80 6 | t.string :telephone, limit: 20 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/owners/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= @owner.id %>

2 | 3 |

Name: <%= @owner.name %>

4 |

City: <%= @owner.city %>

5 |

Telephone: <%= @owner.telephone %>

6 |

Created at: <%= @owner.created_at %>

7 |

Updated at: <%= @owner.updated_at %>

8 | 9 |
    10 |
  • <%= link_to "Owners", "/owners" %>
  • 11 |
-------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/vets/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= @vet.id %>

2 | 3 |

Name: <%= @vet.name %>

4 |

Created at: <%= @vet.created_at %>

5 |

Updated at: <%= @vet.updated_at %>

6 | 7 |
    8 |
  • <%= link_to "Owners", "/owners" %>
  • 9 |
  • <%= link_to "Pets", "/pets" %>
  • 10 |
  • <%= link_to "Vets", "/vets" %>
  • 11 |
-------------------------------------------------------------------------------- /java/pgjdbc_hikaricp/src/test/java/org/example/DsqlHikariCPExampleTest.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | public class DsqlHikariCPExampleTest { 8 | @Test 9 | public void testHikariCPExample() { 10 | assertAll(() -> Example.main(new String[]{})); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/channels/application_cable/connection_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | module ApplicationCable 4 | class ConnectionTest < ActionCable::Connection::TestCase 5 | # test "connects with cookies" do 6 | # cookies.signed[:user_id] = 42 7 | # 8 | # connect 9 | # 10 | # assert_equal connection.user_id, "42" 11 | # end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/.gitattributes: -------------------------------------------------------------------------------- 1 | # See https://git-scm.com/docs/gitattributes for more about git attribute files. 2 | 3 | # Mark the database schema as having been generated. 4 | db/schema.rb linguist-generated 5 | 6 | # Mark any vendored files as having been vendored. 7 | vendor/* linguist-vendored 8 | config/credentials/*.yml.enc diff=rails_credentials 9 | config/credentials.yml.enc diff=rails_credentials 10 | -------------------------------------------------------------------------------- /typescript/type-orm/src/entity/Specialty.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata" 2 | import { Entity, PrimaryColumn, ManyToMany } from "typeorm" 3 | import { Vet } from "./Vet"; 4 | 5 | @Entity("specialty") 6 | export class Specialty { 7 | @PrimaryColumn({ 8 | type: "varchar", 9 | length: 80 10 | }) 11 | name: string; 12 | 13 | @ManyToMany(() => Vet, (vet) => vet.specialties) 14 | vets: Vet[]; 15 | } -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/pets/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= @pet.id %>

2 | 3 |

Name: <%= @pet.name %>

4 |

Date of birth: <%= @pet.birth_date %>

5 |

Owner id: <%= @pet.owner_id %>

6 |

Created at: <%= @pet.created_at %>

7 |

Updated at: <%= @pet.updated_at %>

8 | 9 |
    10 |
  • <%= link_to "Owners", "/owners" %>
  • 11 |
  • <%= link_to "Pets", "/pets" %>
  • 12 |
  • <%= link_to "Vets", "/vets" %>
  • 13 |
-------------------------------------------------------------------------------- /go/.gitignore: -------------------------------------------------------------------------------- 1 | **/.idea/ 2 | pgx/example 3 | 4 | # Binaries for programs and plugins 5 | *.exe 6 | *.exe~ 7 | *.dll 8 | *.so 9 | *.dylib 10 | 11 | # Test binary, built with `go test -c` 12 | *.test 13 | 14 | # Output of the go coverage tool, specifically when used with LiteIDE 15 | *.out 16 | 17 | # Dependency directories (remove the comment below to include it) 18 | # vendor/ 19 | 20 | # Go workspace file 21 | go.work 22 | go.work.sum 23 | 24 | # env file 25 | .env 26 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/models/pet.rb: -------------------------------------------------------------------------------- 1 | class Pet < ApplicationRecord 2 | belongs_to :owner 3 | 4 | validates :name, presence: true, length: { maximum: 30 } 5 | validates :birth_date, presence: true 6 | 7 | # Without this, active record uses all the the columns that are 8 | # part of the primary key index. Unlike postgres, by default, 9 | # Aurora DSQL creates primary key index including all columns in 10 | # the table. 11 | self.primary_key = "id" 12 | end 13 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/bin/docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # Enable jemalloc for reduced memory usage and latency. 4 | if [ -z "${LD_PRELOAD+x}" ] && [ -f /usr/lib/*/libjemalloc.so.2 ]; then 5 | export LD_PRELOAD="$(echo /usr/lib/*/libjemalloc.so.2)" 6 | fi 7 | 8 | # If running the rails server then create or migrate existing database 9 | if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then 10 | ./bin/rails db:prepare 11 | fi 12 | 13 | exec "${@}" 14 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | SzXvzGI5R3ZHqdXnEsLl0dQCSrePJydZpyrByqUyk+Js6wIza1eijr6fktEpu8FIqVJLkmxTMDqnQBgd0ij8U26pfp+S5bpa5o6jkAoxC2KcIYo/Gz7gf8GA6GFfV3bYkEXQ3f7Fq7DlwqqiKJOl/Bq8rVGKHr8zgTFw79zThPaBiRLuzkrQ2vG/Btl6CPaV79jnFA7tayb+Q9XAUy2EO2AIwFI7SweHxcPVsBRPkN17qg+oKk4QJ2XSTerXSeF/p9D0285MjLIDwGvnA+ebXApM+B4kk3fuOj3lHi+QKKBNrXZxDqTLbxx/5v+vxqG+LagT6/vOsR99HZYsjysXbvNNs+qskTInUs49AYXfKJIuj4rIqdS3vq7rjUgwo/uGoUzR26vXYGhFI0C6a4TEYrwoQYRn--f9eT1I+2tpXVqid5--q8peRZ7PQ5UV/t6dn7490g== -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/models/specialty.rb: -------------------------------------------------------------------------------- 1 | class Specialty < ApplicationRecord 2 | has_many :vet_specialties 3 | has_many :vets, through: :vet_specialties 4 | 5 | validates :name, presence: true, length: { maximum: 80 } 6 | 7 | # Without this, active record uses all the the columns that are 8 | # part of the primary key index. Unlike postgres, by default, 9 | # Aurora DSQL creates primary key index including all columns in 10 | # the table. 11 | self.primary_key = "id" 12 | end 13 | -------------------------------------------------------------------------------- /java/spring_boot/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("java") 3 | id("org.springframework.boot") version "3.5.6" 4 | id("io.spring.dependency-management") version "1.1.7" 5 | } 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | implementation("org.springframework.boot:spring-boot-starter-data-jdbc") 13 | implementation("org.springframework.boot:spring-boot-starter-web") 14 | implementation("software.amazon.dsql:aurora-dsql-jdbc-connector:1.2.0") 15 | } 16 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] ||= "test" 2 | require_relative "../config/environment" 3 | require "rails/test_help" 4 | 5 | module ActiveSupport 6 | class TestCase 7 | # Run tests in parallel with specified workers 8 | parallelize(workers: :number_of_processors) 9 | 10 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 11 | fixtures :all 12 | 13 | # Add more helper methods to be used by all tests here... 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/models/vet.rb: -------------------------------------------------------------------------------- 1 | class Vet < ApplicationRecord 2 | has_many :vet_specialties , dependent: :delete_all 3 | has_many :specialties, through: :vet_specialties 4 | 5 | validates :name, presence: true, length: { maximum: 30 } 6 | 7 | # Without this, active record uses all the the columns that are 8 | # part of the primary key index. Unlike postgres, by default, 9 | # Aurora DSQL creates primary key index including all columns in 10 | # the table. 11 | self.primary_key = "id" 12 | end 13 | -------------------------------------------------------------------------------- /.github/workflows/deps-review.yml: -------------------------------------------------------------------------------- 1 | name: 'Dependency Review' 2 | 3 | permissions: {} 4 | 5 | on: [pull_request] 6 | 7 | jobs: 8 | dependency-review: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: read # required by actions/dependency-review-action 12 | steps: 13 | - name: 'Checkout Repository' 14 | uses: actions/checkout@v4 15 | - name: 'Dependency Review' 16 | uses: actions/dependency-review-action@v4 17 | with: 18 | fail-on-severity: moderate 19 | -------------------------------------------------------------------------------- /java/.gitignore: -------------------------------------------------------------------------------- 1 | **/.gradle/ 2 | **/gradle/ 3 | **/bin/ 4 | **/build/ 5 | **/.idea/ 6 | *.iml 7 | **/target/ 8 | **/.classpath/ 9 | **/.project/ 10 | **/.settings/ 11 | **/libs/software/ 12 | **/gradlew 13 | **/gradlew.bat 14 | 15 | # Compiled class file 16 | *.class 17 | 18 | # Log file 19 | *.log 20 | 21 | # BlueJ files 22 | *.ctxt 23 | 24 | # Mobile Tools for Java (J2ME) 25 | .mtj.tmp/ 26 | 27 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 28 | hs_err_pid* 29 | replay_pid* 30 | -------------------------------------------------------------------------------- /python/sqlalchemy/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # NOTE: 4 | # This is only there to help any one from internal dev group to configure their 5 | # environment with a single command. We are not going to write the readme 6 | # using this script for external users 7 | if [ ! -z "$VIRTUAL_ENV" ]; then 8 | echo "Deactivating existing virtual enviornment" 9 | deactivate 10 | fi 11 | python3 -m venv box 12 | source box/bin/activate 13 | pip install --upgrade pip 14 | pip install --force-reinstall -r requirements.txt --no-cache-dir -------------------------------------------------------------------------------- /typescript/prisma/jest.config.js: -------------------------------------------------------------------------------- 1 | const { createDefaultPreset, pathsToModuleNameMapper } = require("ts-jest"); 2 | const { compilerOptions } = require("./tsconfig"); 3 | 4 | const tsJestTransformCfg = createDefaultPreset().transform; 5 | 6 | /** @type {import("jest").Config} **/ 7 | module.exports = { 8 | testEnvironment: "node", 9 | transform: { 10 | ...tsJestTransformCfg, 11 | }, 12 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { 13 | prefix: "/", 14 | }), 15 | }; 16 | -------------------------------------------------------------------------------- /.github/workflows/gitleaks-scan.yml: -------------------------------------------------------------------------------- 1 | name: Gitleaks scan 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [ main ] 8 | pull_request: 9 | branches: [ main ] 10 | 11 | jobs: 12 | test: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout code 17 | uses: actions/checkout@v4 18 | 19 | - name: gitleaks 20 | uses: gitleaks/gitleaks-action@v1.6.0 21 | env: 22 | # GitHub Token automatically created on run 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | -------------------------------------------------------------------------------- /javascript/cluster_management/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cluster-management", 3 | "version": "1.0.0", 4 | "description": "\"Cluster Management CRUD\"", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@aws-sdk/client-dsql": "^3.810.0", 14 | "assert": "^2.1.0" 15 | }, 16 | "devDependencies": { 17 | "jest": "^29.7.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. 4 | # Use this to limit dissemination of sensitive information. 5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. 6 | Rails.application.config.filter_parameters += [ 7 | :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 8 | ] 9 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/pwa/manifest.json.erb: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Petclinic", 3 | "icons": [ 4 | { 5 | "src": "/icon.png", 6 | "type": "image/png", 7 | "sizes": "512x512" 8 | }, 9 | { 10 | "src": "/icon.png", 11 | "type": "image/png", 12 | "sizes": "512x512", 13 | "purpose": "maskable" 14 | } 15 | ], 16 | "start_url": "/", 17 | "display": "standalone", 18 | "scope": "/", 19 | "description": "Petclinic.", 20 | "theme_color": "red", 21 | "background_color": "red" 22 | } 23 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should ensure the existence of records required to run the application in every environment (production, 2 | # development, test). The code here should be idempotent so that it can be executed at any point in every environment. 3 | # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). 4 | # 5 | # Example: 6 | # 7 | # ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| 8 | # MovieGenre.find_or_create_by!(name: genre_name) 9 | # end 10 | -------------------------------------------------------------------------------- /typescript/type-orm/src/entity/VetSpecialty.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | import { Entity, Column, PrimaryColumn } from "typeorm"; 3 | import { v4 as uuidv4 } from "uuid"; 4 | 5 | @Entity("vet_specialty") 6 | export class VetSpecialty { 7 | @PrimaryColumn({ 8 | type: 'varchar', 9 | length: 36, 10 | generatedIdentity: "ALWAYS", 11 | default: "gen_random_uuid()" 12 | }) 13 | id: string; 14 | 15 | constructor() { 16 | if(!this.id) { 17 | this.id = uuidv4(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /rust/sqlx/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sqlx_example" 3 | version = "0.1.0" 4 | edition = "2021" 5 | include = ["/src"] 6 | 7 | [dependencies] 8 | tokio = { version = "1.28", features = ["full"] } 9 | sqlx = { version = "0.8", features = [ "runtime-tokio", "tls-rustls" , "postgres", "uuid"] } 10 | anyhow = { version = "1", features = ["backtrace"] } 11 | aws-config = "1.1" 12 | aws-sdk-dsql = "1.1" 13 | rand = "0.8" 14 | uuid = { version = "1.11", features = ["v4"] } 15 | log = "0.4.27" 16 | 17 | 18 | [[bin]] 19 | name = "sqlx" 20 | path = "src/main.rs" 21 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/initializers/permissions_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide HTTP permissions policy. For further 4 | # information see: https://developers.google.com/web/updates/2018/06/feature-policy 5 | 6 | # Rails.application.config.permissions_policy do |policy| 7 | # policy.camera :none 8 | # policy.gyroscope :none 9 | # policy.microphone :none 10 | # policy.usb :none 11 | # policy.fullscreen :self 12 | # policy.payment :self, "https://secure.example.com" 13 | # end 14 | -------------------------------------------------------------------------------- /typescript/prisma/src/utils.ts: -------------------------------------------------------------------------------- 1 | export const MILLIS_IN_SECOND = 1000; 2 | export const SECONDS_IN_MINUTE = 60; 3 | 4 | /** 5 | * Get the value of the provided environment variable name, or throw if it doesn't exist. 6 | * 7 | * @param name The name of the environment variable to retrieve. 8 | * @return The environment variable value. 9 | */ 10 | export function getRequiredEnv(name: string): string { 11 | const value = process.env[name]; 12 | if (!value) { 13 | throw new Error(`Missing required environment variable ${name}`); 14 | } 15 | return value; 16 | } 17 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = "1.0" 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in the app/assets 11 | # folder are already added. 12 | # Rails.application.config.assets.precompile += %w[ admin.js admin.css ] 13 | -------------------------------------------------------------------------------- /.github/depandabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | 13 | -------------------------------------------------------------------------------- /ruby/cluster_management/lib/get_cluster.rb: -------------------------------------------------------------------------------- 1 | require "aws-sdk-dsql" 2 | require "pp" 3 | 4 | def get_cluster(region, identifier) 5 | client = Aws::DSQL::Client.new(region: region) 6 | client.get_cluster(identifier: identifier) 7 | rescue Aws::Errors::ServiceError => e 8 | abort "Unable to retrieve cluster #{identifier} in region #{region}: #{e.message}" 9 | end 10 | 11 | def main 12 | region = ENV.fetch("CLUSTER_REGION", "us-east-1") 13 | cluster_id = ENV.fetch("CLUSTER_ID") 14 | cluster = get_cluster(region, cluster_id) 15 | pp cluster 16 | end 17 | 18 | main if $PROGRAM_NAME == __FILE__ 19 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/models/owner.rb: -------------------------------------------------------------------------------- 1 | class Owner < ApplicationRecord 2 | has_many :pets, dependent: :destroy 3 | has_one :vet 4 | 5 | validates :name, presence: true, length: { maximum: 30 } 6 | validates :city, presence: true, length: { maximum: 80 } 7 | validates :telephone, presence: false, length: { maximum: 20 } 8 | 9 | # Without this, active record uses all the the columns that are 10 | # part of the primary key index. Unlike postgres, by default, 11 | # Aurora DSQL creates primary key index including all columns in 12 | # the table. 13 | self.primary_key = "id" 14 | end 15 | -------------------------------------------------------------------------------- /typescript/type-orm/src/utils.ts: -------------------------------------------------------------------------------- 1 | export const getEnvironmentVariables = () => { 2 | const user = process.env.CLUSTER_USER; 3 | const clusterEndpoint = process.env.CLUSTER_ENDPOINT; 4 | const region = process.env.REGION; 5 | 6 | if (!clusterEndpoint || !region || !user) { 7 | throw new Error( 8 | `Missing required environment variables: ${[ 9 | !user && "CLUSTER_USER", 10 | !clusterEndpoint && "CLUSTER_ENDPOINT", 11 | !region && "REGION", 12 | ] 13 | .filter(Boolean) 14 | .join(", ")}` 15 | ); 16 | } 17 | 18 | return { user, clusterEndpoint, region }; 19 | }; 20 | -------------------------------------------------------------------------------- /javascript/node-postgres/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dsql_nodejs_howto", 3 | "version": "1.0.0", 4 | "description": "How To", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "test": "node --experimental-vm-modules node_modules/.bin/jest --testPathPattern='test/smoke.test.js' --runInBand --detectOpenHandles --forceExit" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@aws-sdk/dsql-signer": "^3.705.0", 14 | "assert": "2.1.0", 15 | "pg": "^8.13.1", 16 | "uuid": "^11.0.2" 17 | }, 18 | "devDependencies": { 19 | "jest": "^29.7.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /javascript/postgres-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dsql_postgres_howto", 3 | "version": "1.0.0", 4 | "description": "How To", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "test": "node --experimental-vm-modules node_modules/.bin/jest --testPathPattern='test/smoke.test.js' --runInBand --detectOpenHandles --forceExit" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@aws-sdk/dsql-signer": "^3.758.0", 14 | "assert": "2.1.0", 15 | "postgres": "^3.4.5", 16 | "uuid": "^11.0.2" 17 | }, 18 | "devDependencies": { 19 | "jest": "^29.7.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ruby/cluster_management/lib/update_cluster.rb: -------------------------------------------------------------------------------- 1 | require "aws-sdk-dsql" 2 | 3 | def update_cluster(region, update_params) 4 | client = Aws::DSQL::Client.new(region: region) 5 | client.update_cluster(update_params) 6 | rescue Aws::Errors::ServiceError => e 7 | abort "Unable to update cluster: #{e.message}" 8 | end 9 | 10 | def main 11 | region = ENV.fetch("CLUSTER_REGION", "us-east-1") 12 | cluster_id = ENV.fetch("CLUSTER_ID") 13 | updated_cluster = update_cluster(region, { 14 | identifier: cluster_id, 15 | deletion_protection_enabled: false 16 | }) 17 | puts "Updated #{updated_cluster.arn}" 18 | end 19 | 20 | main if $PROGRAM_NAME == __FILE__ 21 | -------------------------------------------------------------------------------- /java/spring_boot/src/main/java/org/example/ApiController.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import org.springframework.jdbc.core.JdbcTemplate; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | @RestController 8 | public class ApiController { 9 | 10 | private final JdbcTemplate jdbcTemplate; 11 | 12 | public ApiController(final JdbcTemplate jdbcTemplate) { 13 | this.jdbcTemplate = jdbcTemplate; 14 | } 15 | 16 | @GetMapping(value = "/select1") 17 | public Integer getOne() { 18 | return jdbcTemplate.queryForObject("SELECT 1;", Integer.class); 19 | } 20 | } -------------------------------------------------------------------------------- /quickstart_data/department-insert-multirow.sql: -------------------------------------------------------------------------------- 1 | BEGIN; 2 | INSERT INTO example.department(id, name, email) VALUES 3 | (1, 'Example Department One', 'example+one@example.com'), 4 | (2, 'Example Department Two', 'example+two@example.com'), 5 | (3, 'Example Department Three', 'example+three@example.com'), 6 | (4, 'Example Department Four', 'example+four@example.com'), 7 | (5, 'Example Department Five', 'example+five@example.com'), 8 | (6, 'Example Department Six', 'example+six@example.com'), 9 | (7, 'Example Department Seven', 'example+seven@example.com'), 10 | (8, 'Example Department Eight', 'example+eight@example.com'), 11 | (9, 'Example Department Nine', 'example+nine@example.com'); 12 | COMMIT; 13 | -------------------------------------------------------------------------------- /.github/workflows/close-issue-message.yml: -------------------------------------------------------------------------------- 1 | name: Closed Issue Message 2 | 3 | permissions: {} 4 | 5 | on: 6 | issues: 7 | types: [closed] 8 | 9 | jobs: 10 | auto_comment: 11 | permissions: 12 | issues: write # to comment on issues 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: aws-actions/closed-issue-message@v1 16 | with: 17 | # These inputs are both required 18 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 19 | message: | 20 | This issue is now closed. Comments on closed issues are hard for our team to see. 21 | If you need more assistance, please open a new issue that references this one. -------------------------------------------------------------------------------- /rust/cluster_management/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This file re-exports the functions from the example files so they can be used in tests 2 | 3 | pub mod create_multi_region_clusters { 4 | include!("bin/create_multi_region_clusters.rs"); 5 | } 6 | 7 | pub mod create_single_region_cluster { 8 | include!("bin/create_single_region_cluster.rs"); 9 | } 10 | 11 | pub mod delete_multi_region_clusters { 12 | include!("bin/delete_multi_region_clusters.rs"); 13 | } 14 | 15 | pub mod delete_single_region_cluster { 16 | include!("bin/delete_single_region_cluster.rs"); 17 | } 18 | 19 | pub mod get_cluster { 20 | include!("bin/get_cluster.rs"); 21 | } 22 | 23 | pub mod update_cluster { 24 | include!("bin/update_cluster.rs"); 25 | } 26 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "✨ Feature Request" 3 | about: Request a new sample or enhancements to existing samples 4 | title: "(language) (short description)" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /dotnet/npgsql/example.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | 6 | net9.0 7 | 10 8 | 9 | enable 10 | enable 11 | false 12 | false 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html 3 | 4 | # # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. 5 | # # Can be used by load balancers and uptime monitors to verify that the app is live. 6 | # get "up" => "rails/health#show", as: :rails_health_check 7 | 8 | # # Render dynamic PWA files from app/views/pwa/* 9 | # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker 10 | # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest 11 | 12 | # Defines the root path route ("/") 13 | # root "posts#index" 14 | 15 | root "owners#index" 16 | resources :owners 17 | resources :pets 18 | resources :vets 19 | end 20 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's 6 | * vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS 10 | * files in this directory. Styles in this file should be added after the last require_* statement. 11 | * It is generally better to create a new file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= content_for(:title) || "Petclinic" %> 5 | 6 | 7 | <%= csrf_meta_tags %> 8 | <%= csp_meta_tag %> 9 | 10 | <%= yield :head %> 11 | 12 | 13 | 14 | 15 | 16 | <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> 17 | <%= javascript_importmap_tags %> 18 | 19 | 20 | 21 | <%= yield %> 22 | 23 | 24 | -------------------------------------------------------------------------------- /typescript/prisma/src/index.ts: -------------------------------------------------------------------------------- 1 | import { runVeterinaryExample } from "./example"; 2 | import { DsqlPrismaClient } from "./dsql-client"; 3 | import { VeterinaryService } from "./veterinary-service"; 4 | 5 | async function main() { 6 | console.log("Starting Prisma DSQL Example..."); 7 | 8 | try { 9 | const client = new DsqlPrismaClient(); 10 | try { 11 | const service = new VeterinaryService(client); 12 | await runVeterinaryExample(service); 13 | console.log("Example completed successfully!"); 14 | } finally { 15 | await client.dispose(); 16 | } 17 | } catch (error) { 18 | console.error("Error running example:", error); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | if (require.main === module) { 24 | main().catch(console.error); 25 | } 26 | -------------------------------------------------------------------------------- /python/cluster_management/src/get_cluster.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import os 3 | from datetime import datetime 4 | import json 5 | 6 | 7 | def get_cluster(region, identifier): 8 | try: 9 | client = boto3.client("dsql", region_name=region) 10 | return client.get_cluster(identifier=identifier) 11 | except: 12 | print(f"Unable to get cluster {identifier} in region {region}") 13 | raise 14 | 15 | 16 | def main(): 17 | region = os.environ.get("CLUSTER_REGION", "us-east-1") 18 | cluster_id = os.environ.get("CLUSTER_ID") 19 | assert cluster_id is not None, "Must provide CLUSTER_ID" 20 | response = get_cluster(region, cluster_id) 21 | 22 | print(json.dumps(response, indent=2, default=lambda obj: obj.isoformat() if isinstance(obj, datetime) else None)) 23 | 24 | 25 | if __name__ == "__main__": 26 | main() 27 | -------------------------------------------------------------------------------- /typescript/sequelize/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xanadu_postgres_howto", 3 | "version": "1.0.0", 4 | "description": "How To", 5 | "main": "index.js", 6 | "type": "commonjs", 7 | "scripts": { 8 | "build": "tsc", 9 | "clean": "rm -rf build && rm -rf dist", 10 | "start": "node dist/src/index.js", 11 | "dev": "npm run clean && npm run build && npm run start", 12 | "test": "npm run clean && npm run build && jest dist/test" 13 | }, 14 | "dependencies": { 15 | "@aws-sdk/dsql-signer": "^3.705.0", 16 | "pg": "^8.13.1", 17 | "pg-hstore": "^2.3.4", 18 | "pg-native": "^3.2.0", 19 | "sequelize": "^6.37.5" 20 | }, 21 | "devDependencies": { 22 | "@types/jest": "^29.5.14", 23 | "jest": "^29.7.0", 24 | "typescript": "^5.0.0" 25 | } 26 | } -------------------------------------------------------------------------------- /rust/.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | debug/ 4 | target/ 5 | 6 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 7 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 8 | Cargo.lock 9 | 10 | # These are backup files generated by rustfmt 11 | **/*.rs.bk 12 | 13 | # MSVC Windows builds of rustc generate these, which store debugging information 14 | *.pdb 15 | 16 | # RustRover 17 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 18 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 19 | # and can be added to the global gitignore or merged into this file. For a more nuclear 20 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 21 | #.idea/ 22 | -------------------------------------------------------------------------------- /java/spring_boot/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | cluster: 2 | user: ${CLUSTER_USER} 3 | endpoint: ${CLUSTER_ENDPOINT} 4 | 5 | app: 6 | exit-after-test: ${EXIT_AFTER_TEST:false} 7 | 8 | spring: 9 | datasource: 10 | url: jdbc:aws-dsql:postgresql://${cluster.endpoint} 11 | username: ${cluster.user} 12 | driver-class-name: software.amazon.dsql.jdbc.DSQLConnector 13 | hikari: 14 | max-lifetime: 1800000 # 30 minutes (shorter than Aurora DSQL's 60-minute limit) 15 | minimum-idle: 2 16 | maximum-pool-size: 10 17 | idle-timeout: 300000 # 5 minutes 18 | connection-timeout: 30000 # 30 seconds 19 | validation-timeout: 5000 # 5 seconds 20 | connection-test-query: "SELECT 1" 21 | data-source-properties: 22 | sslmode: verify-full 23 | sslfactory: org.postgresql.ssl.DefaultJavaSSLFactory 24 | sslnegotiation: direct 25 | -------------------------------------------------------------------------------- /python/cluster_management/src/update_cluster.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import os 3 | 4 | 5 | def update_cluster(region, cluster_id, deletion_protection_enabled): 6 | try: 7 | client = boto3.client("dsql", region_name=region) 8 | return client.update_cluster(identifier=cluster_id, deletionProtectionEnabled=deletion_protection_enabled) 9 | except: 10 | print("Unable to update cluster") 11 | raise 12 | 13 | 14 | def main(): 15 | region = os.environ.get("CLUSTER_REGION", "us-east-1") 16 | cluster_id = os.environ.get("CLUSTER_ID") 17 | assert cluster_id is not None, "Must provide CLUSTER_ID" 18 | deletion_protection_enabled = False 19 | response = update_cluster(region, cluster_id, deletion_protection_enabled) 20 | print(f"Updated {response['arn']} with deletion_protection_enabled: {deletion_protection_enabled}") 21 | 22 | 23 | if __name__ == "__main__": 24 | main() 25 | -------------------------------------------------------------------------------- /typescript/prisma/prisma/migrations/0_init/down.sql: -------------------------------------------------------------------------------- 1 | -- Migration initially generated using the following command: 2 | -- 3 | -- npx prisma migrate diff 4 | -- --from-schema-datamodel prisma/veterinary-schema.prisma 5 | -- --to-empty 6 | -- --script 7 | -- > prisma/migrations/0_init/down.sql 8 | -- 9 | -- Manual changes were made based on the considerations mentioned in the project README.md file. 10 | 11 | -- DropTable 12 | BEGIN; 13 | DROP TABLE IF EXISTS "owner"; 14 | COMMIT; 15 | 16 | -- DropTable 17 | BEGIN; 18 | DROP TABLE IF EXISTS "pet"; 19 | COMMIT; 20 | 21 | -- DropTable 22 | BEGIN; 23 | DROP TABLE IF EXISTS "specialty"; 24 | COMMIT; 25 | 26 | -- DropTable 27 | BEGIN; 28 | DROP TABLE IF EXISTS "vet"; 29 | COMMIT; 30 | 31 | -- DropTable 32 | BEGIN; 33 | DROP TABLE IF EXISTS "_SpecialtyToVet"; 34 | COMMIT; 35 | 36 | BEGIN; 37 | DROP TABLE IF EXISTS "_prisma_migrations"; 38 | COMMIT; -------------------------------------------------------------------------------- /ruby/rails/petclinic/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # Temporary files generated by your text editor or operating system 4 | # belong in git's global ignore instead: 5 | # `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore` 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all environment files (except templates). 11 | /.env* 12 | !/.env*.erb 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | /tmp/* 17 | !/log/.keep 18 | !/tmp/.keep 19 | 20 | # Ignore pidfiles, but keep the directory. 21 | /tmp/pids/* 22 | !/tmp/pids/ 23 | !/tmp/pids/.keep 24 | 25 | # Ignore storage (uploaded files in development and any SQLite databases). 26 | /storage/* 27 | !/storage/.keep 28 | /tmp/storage/* 29 | !/tmp/storage/ 30 | !/tmp/storage/.keep 31 | 32 | /public/assets 33 | 34 | # Ignore master key for decrypting credentials and more. 35 | /config/master.key 36 | -------------------------------------------------------------------------------- /ruby/cluster_management/lib/delete_single_region_cluster.rb: -------------------------------------------------------------------------------- 1 | require "aws-sdk-dsql" 2 | 3 | def delete_cluster(region, identifier) 4 | client = Aws::DSQL::Client.new(region: region) 5 | cluster = client.delete_cluster(identifier: identifier) 6 | puts "Initiated delete of #{cluster.arn}" 7 | 8 | # The DSQL SDK offers built-in waiters to poll for deletion. 9 | puts "Waiting for cluster to finish deletion" 10 | client.wait_until(:cluster_not_exists, identifier: cluster.identifier) do |w| 11 | # Wait for 5 minutes 12 | w.max_attempts = 30 13 | w.delay = 10 14 | end 15 | rescue Aws::Errors::ServiceError => e 16 | abort "Unable to delete cluster #{identifier} in #{region}: #{e.message}" 17 | end 18 | 19 | def main 20 | region = ENV.fetch("CLUSTER_REGION", "us-east-1") 21 | cluster_id = ENV.fetch("CLUSTER_ID") 22 | delete_cluster(region, cluster_id) 23 | puts "Deleted #{cluster_id}" 24 | end 25 | 26 | main if $PROGRAM_NAME == __FILE__ 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT No Attribution 2 | 3 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 13 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 15 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/views/pwa/service-worker.js: -------------------------------------------------------------------------------- 1 | // Add a service worker for processing Web Push notifications: 2 | // 3 | // self.addEventListener("push", async (event) => { 4 | // const { title, options } = await event.data.json() 5 | // event.waitUntil(self.registration.showNotification(title, options)) 6 | // }) 7 | // 8 | // self.addEventListener("notificationclick", function(event) { 9 | // event.notification.close() 10 | // event.waitUntil( 11 | // clients.matchAll({ type: "window" }).then((clientList) => { 12 | // for (let i = 0; i < clientList.length; i++) { 13 | // let client = clientList[i] 14 | // let clientPath = (new URL(client.url)).pathname 15 | // 16 | // if (clientPath == event.notification.data.path && "focus" in client) { 17 | // return client.focus() 18 | // } 19 | // } 20 | // 21 | // if (clients.openWindow) { 22 | // return clients.openWindow(event.notification.data.path) 23 | // } 24 | // }) 25 | // ) 26 | // }) 27 | -------------------------------------------------------------------------------- /go/cluster_management/go.mod: -------------------------------------------------------------------------------- 1 | module example 2 | 3 | go 1.24 4 | 5 | require ( 6 | github.com/aws/aws-sdk-go-v2 v1.36.3 7 | github.com/aws/aws-sdk-go-v2/config v1.29.14 8 | github.com/aws/aws-sdk-go-v2/service/dsql v1.3.0 9 | ) 10 | 11 | require ( 12 | github.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect 13 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect 14 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect 15 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect 16 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect 17 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect 18 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect 19 | github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect 20 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect 21 | github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect 22 | github.com/aws/smithy-go v1.22.2 // indirect 23 | ) 24 | -------------------------------------------------------------------------------- /typescript/type-orm/src/entity/Owner.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | import { Column, Entity, PrimaryColumn, OneToMany } from "typeorm"; 3 | import { Pet } from "./Pet"; 4 | import { v4 as uuidv4 } from "uuid"; 5 | 6 | @Entity("owner") 7 | export class Owner { 8 | @PrimaryColumn({ 9 | type: 'varchar', 10 | length: 36, 11 | generatedIdentity: "ALWAYS", 12 | default: "gen_random_uuid()" 13 | }) 14 | id: string; 15 | 16 | @Column({ 17 | length: 30, 18 | nullable: false 19 | }) 20 | name: string; 21 | 22 | @Column({ 23 | length: 80, 24 | nullable: false 25 | }) 26 | city: string; 27 | 28 | @Column({ 29 | length: 20, 30 | nullable: true 31 | }) 32 | telephone: string; 33 | 34 | @OneToMany(() => Pet, (pet: Pet) => pet.owner, { 35 | cascade: true 36 | }) 37 | pets: Pet[]; 38 | 39 | constructor() { 40 | if(!this.id) { 41 | this.id = uuidv4(); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /go/cluster_management/internal/util/disable_delete_protect.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "context" 5 | "github.com/aws/aws-sdk-go-v2/config" 6 | "github.com/aws/aws-sdk-go-v2/service/dsql" 7 | "log" 8 | ) 9 | 10 | func UpdateCluster(ctx context.Context, region, id string, deleteProtection bool) (clusterStatus *dsql.UpdateClusterOutput, err error) { 11 | 12 | cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region)) 13 | if err != nil { 14 | log.Fatalf("Failed to load AWS configuration: %v", err) 15 | } 16 | 17 | // Initialize the DSQL client 18 | client := dsql.NewFromConfig(cfg) 19 | 20 | input := dsql.UpdateClusterInput{ 21 | Identifier: &id, 22 | DeletionProtectionEnabled: &deleteProtection, 23 | } 24 | 25 | clusterStatus, err = client.UpdateCluster(context.Background(), &input) 26 | 27 | if err != nil { 28 | log.Fatalf("Failed to update cluster: %v", err) 29 | } 30 | 31 | log.Printf("Cluster updated successfully: %v", clusterStatus.Status) 32 | return clusterStatus, nil 33 | } 34 | -------------------------------------------------------------------------------- /ruby/cluster_management/lib/create_single_region_cluster.rb: -------------------------------------------------------------------------------- 1 | require "aws-sdk-dsql" 2 | require "pp" 3 | 4 | def create_cluster(region) 5 | client = Aws::DSQL::Client.new(region: region) 6 | cluster = client.create_cluster( 7 | deletion_protection_enabled: true, 8 | tags: { 9 | Name: "Ruby-CM-Example-Single-Region", 10 | Repo: "aws-samples/aurora-dsql-samples" 11 | } 12 | ) 13 | puts "Created #{cluster.arn}" 14 | 15 | # The DSQL SDK offers built-in waiters to poll for a cluster's 16 | # transition to ACTIVE. 17 | puts "Waiting for cluster to become ACTIVE" 18 | client.wait_until(:cluster_active, identifier: cluster.identifier) do |w| 19 | # Wait for 5 minutes 20 | w.max_attempts = 30 21 | w.delay = 10 22 | end 23 | rescue Aws::Errors::ServiceError => e 24 | abort "Unable to create cluster in #{region}: #{e.message}" 25 | end 26 | 27 | def main 28 | region = ENV.fetch("CLUSTER_REGION", "us-east-1") 29 | cluster = create_cluster(region) 30 | pp cluster 31 | end 32 | 33 | main if $PROGRAM_NAME == __FILE__ 34 | -------------------------------------------------------------------------------- /javascript/cluster_management/src/get_cluster.js: -------------------------------------------------------------------------------- 1 | import { DSQLClient, GetClusterCommand } from "@aws-sdk/client-dsql"; 2 | 3 | export async function getCluster(region, clusterId) { 4 | 5 | const client = new DSQLClient({ region }); 6 | 7 | const getClusterCommand = new GetClusterCommand({ 8 | identifier: clusterId, 9 | }); 10 | 11 | try { 12 | return await client.send(getClusterCommand); 13 | } catch (error) { 14 | if (error.name === "ResourceNotFoundException") { 15 | console.log("Cluster ID not found or deleted"); 16 | } 17 | throw error; 18 | } 19 | } 20 | 21 | async function main() { 22 | const region = process.env.CLUSTER_REGION || "us-east-1"; 23 | const clusterId = process.env.CLUSTER_ID; 24 | 25 | if (!clusterId) { 26 | console.error("Error: CLUSTER_ID environment variables must be set"); 27 | process.exit(1); 28 | } 29 | 30 | const response = await getCluster(region, clusterId); 31 | console.log("Cluster: ", response); 32 | } 33 | 34 | if (process.env.NODE_ENV !== 'test') { 35 | main(); 36 | } 37 | -------------------------------------------------------------------------------- /java/spring_boot/src/main/java/org/example/DataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import com.zaxxer.hikari.HikariDataSource; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | import javax.sql.DataSource; 11 | 12 | @Configuration 13 | public class DataSourceConfig { 14 | 15 | @Bean 16 | @ConfigurationProperties("spring.datasource.hikari") 17 | public DataSource dataSource(DataSourceProperties properties, @Value("${cluster.user}") String username) { 18 | HikariDataSource dataSource = properties.initializeDataSourceBuilder().type(HikariDataSource.class).build(); 19 | if (!username.equals("admin")) { 20 | dataSource.setConnectionInitSql("SET search_path=myschema"); 21 | } 22 | return dataSource; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization and 2 | # are automatically loaded by Rails. If you want to use locales other than 3 | # English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t "hello" 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t("hello") %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more about the API, please read the Rails Internationalization guide 20 | # at https://guides.rubyonrails.org/i18n.html. 21 | # 22 | # Be aware that YAML interprets the following case-insensitive strings as 23 | # booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings 24 | # must be quoted to be interpreted as strings. For example: 25 | # 26 | # en: 27 | # "yes": yup 28 | # enabled: "ON" 29 | 30 | en: 31 | hello: "Hello world" 32 | -------------------------------------------------------------------------------- /typescript/type-orm/src/entity/Pet.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | import { Column, Entity, ManyToOne, PrimaryColumn, JoinColumn, RelationId } from "typeorm"; 3 | import { Owner } from "./Owner"; 4 | import { v4 as uuidv4 } from "uuid"; 5 | 6 | @Entity("pet") 7 | export class Pet { 8 | @PrimaryColumn({ 9 | type: 'varchar', 10 | length: 36, 11 | generatedIdentity: "ALWAYS", 12 | default: "gen_random_uuid()" 13 | }) 14 | id: string; 15 | 16 | @Column({ 17 | length: 30, 18 | nullable: false 19 | }) 20 | name: string; 21 | 22 | @Column({ 23 | name: "birth_date", 24 | nullable: false 25 | }) 26 | birthDate: Date; 27 | 28 | @ManyToOne(() => Owner, (owner: Owner) => owner.pets, { 29 | onDelete: "CASCADE", 30 | }) 31 | @JoinColumn({ 32 | name: "owner_id", 33 | referencedColumnName: "id" 34 | }) 35 | owner: Owner; 36 | 37 | constructor() { 38 | if (!this.id) { 39 | this.id = uuidv4(); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /python/cluster_management/src/delete_single_region.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import os 3 | 4 | 5 | def delete_cluster(region, identifier): 6 | try: 7 | client = boto3.client("dsql", region_name=region) 8 | cluster = client.delete_cluster(identifier=identifier) 9 | print(f"Initiated delete of {cluster['arn']}") 10 | 11 | print("Waiting for cluster to finish deletion") 12 | client.get_waiter("cluster_not_exists").wait( 13 | identifier=cluster["identifier"], 14 | WaiterConfig={ 15 | 'Delay': 10, 16 | 'MaxAttempts': 50 17 | } 18 | ) 19 | except: 20 | print("Unable to delete cluster " + identifier) 21 | raise 22 | 23 | 24 | def main(): 25 | region = os.environ.get("CLUSTER_REGION", "us-east-1") 26 | cluster_id = os.environ.get("CLUSTER_ID") 27 | assert cluster_id is not None, "Must provide CLUSTER_ID" 28 | delete_cluster(region, cluster_id) 29 | print(f"Deleted {cluster_id}") 30 | 31 | 32 | if __name__ == "__main__": 33 | main() 34 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/app/controllers/owners_controller.rb: -------------------------------------------------------------------------------- 1 | class OwnersController < ApplicationController 2 | def index 3 | @owners = Owner.all 4 | end 5 | 6 | def show 7 | @owner = Owner.find(params[:id]) 8 | end 9 | 10 | def new 11 | @owner = Owner.new 12 | end 13 | 14 | def create 15 | @owner = Owner.new(owner_params) 16 | 17 | if @owner.save 18 | redirect_to @owner 19 | else 20 | render :new, status: :unprocessable_entity 21 | end 22 | end 23 | 24 | def edit 25 | @owner = Owner.find(params[:id]) 26 | end 27 | 28 | def update 29 | @owner = Owner.find(params[:id]) 30 | 31 | if @owner.update(owner_params) 32 | redirect_to @owner 33 | else 34 | render :edit, status: :unprocessable_entity 35 | end 36 | end 37 | 38 | def destroy 39 | @owner = Owner.find(params[:id]) 40 | @owner.destroy 41 | 42 | redirect_to root_path, status: :see_other 43 | end 44 | 45 | private 46 | def owner_params 47 | params.require(:owner).permit(:name, :city, :telephone) 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /java/pgjdbc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.gradle.api.tasks.testing.logging.TestExceptionFormat 2 | 3 | plugins { 4 | id("java") 5 | id("application") 6 | } 7 | 8 | application { 9 | mainClass = "org.example.Example" 10 | } 11 | 12 | group = "org.example" 13 | version = "1.0-SNAPSHOT" 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | implementation("software.amazon.dsql:aurora-dsql-jdbc-connector:1.2.0") 21 | 22 | testImplementation(platform("org.junit:junit-bom:5.10.0")) 23 | testImplementation("org.junit.jupiter:junit-jupiter") 24 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 25 | } 26 | 27 | tasks.test { 28 | useJUnitPlatform() 29 | 30 | testLogging { 31 | events("passed", "skipped", "failed", "standardOut", "standardError") 32 | exceptionFormat = TestExceptionFormat.FULL 33 | } 34 | } 35 | 36 | tasks.withType { 37 | this.testLogging { 38 | this.showStandardStreams = true 39 | } 40 | } 41 | 42 | tasks.withType { 43 | this.enableAssertions = true 44 | } -------------------------------------------------------------------------------- /ruby/rails/petclinic/.dockerignore: -------------------------------------------------------------------------------- 1 | # See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. 2 | 3 | # Ignore git directory. 4 | /.git/ 5 | /.gitignore 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all environment files (except templates). 11 | /.env* 12 | !/.env*.erb 13 | 14 | # Ignore all default key files. 15 | /config/master.key 16 | /config/credentials/*.key 17 | 18 | # Ignore all logfiles and tempfiles. 19 | /log/* 20 | /tmp/* 21 | !/log/.keep 22 | !/tmp/.keep 23 | 24 | # Ignore pidfiles, but keep the directory. 25 | /tmp/pids/* 26 | !/tmp/pids/.keep 27 | 28 | # Ignore storage (uploaded files in development and any SQLite databases). 29 | /storage/* 30 | !/storage/.keep 31 | /tmp/storage/* 32 | !/tmp/storage/.keep 33 | 34 | # Ignore assets. 35 | /node_modules/ 36 | /app/assets/builds/* 37 | !/app/assets/builds/.keep 38 | /public/assets 39 | 40 | # Ignore CI service files. 41 | /.github 42 | 43 | # Ignore development files 44 | /.devcontainer 45 | 46 | # Ignore Docker-related files 47 | /.dockerignore 48 | /Dockerfile* 49 | -------------------------------------------------------------------------------- /javascript/cluster_management/src/update_cluster.js: -------------------------------------------------------------------------------- 1 | import { DSQLClient, UpdateClusterCommand } from "@aws-sdk/client-dsql"; 2 | 3 | export async function updateCluster(region, clusterId, deletionProtectionEnabled) { 4 | 5 | const client = new DSQLClient({ region }); 6 | 7 | const updateClusterCommand = new UpdateClusterCommand({ 8 | identifier: clusterId, 9 | deletionProtectionEnabled: deletionProtectionEnabled 10 | }); 11 | 12 | try { 13 | return await client.send(updateClusterCommand); 14 | } catch (error) { 15 | console.error("Unable to update cluster", error.message); 16 | throw error; 17 | } 18 | } 19 | 20 | async function main() { 21 | const region = process.env.CLUSTER_REGION || "us-east-1"; 22 | const clusterId = process.env.CLUSTER_ID; 23 | 24 | if (!clusterId) { 25 | console.error("Error: CLUSTER_ID environment variables must be set"); 26 | process.exit(1); 27 | } 28 | 29 | const response = await updateCluster(region, clusterId, false); 30 | console.log(`Updated ${response.arn}`); 31 | } 32 | 33 | if (process.env.NODE_ENV !== 'test') { 34 | main(); 35 | } 36 | -------------------------------------------------------------------------------- /typescript/prisma/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "commonjs", 5 | "lib": ["es2022"], 6 | "outDir": "./dist", 7 | "rootDir": ".", 8 | "strict": true, 9 | "noUnusedLocals": true, 10 | "noUnusedParameters": true, 11 | "exactOptionalPropertyTypes": true, 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "noUncheckedIndexedAccess": true, 15 | "esModuleInterop": true, 16 | "allowSyntheticDefaultImports": true, 17 | "skipLibCheck": true, 18 | "forceConsistentCasingInFileNames": true, 19 | "resolveJsonModule": true, 20 | "isolatedModules": true, 21 | "declaration": true, 22 | "declarationMap": true, 23 | "sourceMap": true, 24 | "removeComments": true, 25 | "baseUrl": ".", 26 | "paths": { 27 | "@generated/*": ["./generated/*"] 28 | } 29 | }, 30 | "include": ["src/**/*", "generated/**/*"], 31 | "exclude": ["node_modules", "dist", "test"] 32 | } 33 | -------------------------------------------------------------------------------- /python/cluster_management/src/create_single_region.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import os 3 | 4 | 5 | def create_cluster(region): 6 | try: 7 | client = boto3.client("dsql", region_name=region) 8 | tags = {"Name": "Python-CM-Example-Single-Region", "Repo": "aws-samples/aurora-dsql-samples"} 9 | cluster = client.create_cluster(tags=tags, deletionProtectionEnabled=True) 10 | print(f"Initiated creation of cluster: {cluster['identifier']}") 11 | 12 | print(f"Waiting for {cluster['arn']} to become ACTIVE") 13 | client.get_waiter("cluster_active").wait( 14 | identifier=cluster["identifier"], 15 | WaiterConfig={ 16 | 'Delay': 10, 17 | 'MaxAttempts': 50 18 | } 19 | ) 20 | 21 | return cluster 22 | except: 23 | print("Unable to create cluster") 24 | raise 25 | 26 | 27 | def main(): 28 | region = os.environ.get("CLUSTER_REGION", "us-east-1") 29 | response = create_cluster(region) 30 | print(f"Created cluster: {response['arn']}") 31 | 32 | 33 | if __name__ == "__main__": 34 | main() 35 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails/all" 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module Petclinic 10 | class Application < Rails::Application 11 | # Initialize configuration defaults for originally generated Rails version. 12 | config.load_defaults 7.2 13 | 14 | # Please, add to the `ignore` list any other `lib` subdirectories that do 15 | # not contain `.rb` files, or that should not be reloaded or eager loaded. 16 | # Common ones are `templates`, `generators`, or `middleware`, for example. 17 | config.autoload_lib(ignore: %w[assets tasks]) 18 | 19 | # Configuration for the application, engines, and railties goes here. 20 | # 21 | # These settings can be overridden in specific environments using the files 22 | # in config/environments, which are processed later. 23 | # 24 | # config.time_zone = "Central Time (US & Canada)" 25 | # config.eager_load_paths << Rails.root.join("extras") 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /java/pgjdbc_hikaricp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.gradle.api.tasks.testing.logging.TestExceptionFormat 2 | 3 | plugins { 4 | id("java") 5 | id("application") 6 | } 7 | 8 | application { 9 | mainClass = "org.example.Example" 10 | } 11 | 12 | group = "org.example" 13 | version = "1.0-SNAPSHOT" 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | implementation("com.zaxxer:HikariCP:5.1.0") 21 | implementation("software.amazon.dsql:aurora-dsql-jdbc-connector:1.2.0") 22 | 23 | testImplementation(platform("org.junit:junit-bom:5.10.0")) 24 | testImplementation("org.junit.jupiter:junit-jupiter") 25 | testRuntimeOnly("org.junit.platform:junit-platform-launcher") 26 | } 27 | 28 | tasks.test { 29 | useJUnitPlatform() 30 | 31 | testLogging { 32 | events("passed", "skipped", "failed", "standardOut", "standardError") 33 | exceptionFormat = TestExceptionFormat.FULL 34 | } 35 | } 36 | 37 | tasks.withType { 38 | this.testLogging { 39 | this.showStandardStreams = true 40 | } 41 | } 42 | 43 | tasks.withType { 44 | this.enableAssertions = true 45 | } 46 | -------------------------------------------------------------------------------- /go/cluster_management/Makefile: -------------------------------------------------------------------------------- 1 | # Build all cluster management examples 2 | # Go parameters 3 | GOCMD=go 4 | GOBUILD=$(GOCMD) build 5 | GOCLEAN=$(GOCMD) clean 6 | BINARY_DIR=bin 7 | TEST_FLAGS=-v -count=1 8 | 9 | # Find all cmd directories 10 | CMD_DIRS := $(notdir $(wildcard cmd/*)) 11 | BINARIES := $(addprefix $(BINARY_DIR)/,$(CMD_DIRS)) 12 | 13 | # Default target 14 | .PHONY: all 15 | all: clean build 16 | 17 | .PHONY: test 18 | test: test-all 19 | 20 | # Test all commands 21 | .PHONY: test-all 22 | test-all: $(addprefix test-,$(CMD_DIRS)) 23 | 24 | # Rule to test each command individually 25 | .PHONY: test-% 26 | test-%: 27 | $(GOCMD) test $(TEST_FLAGS) ./cmd/$* 28 | 29 | # Create bin directory 30 | $(BINARY_DIR): 31 | mkdir -p $(BINARY_DIR) 32 | 33 | # Build all commands 34 | .PHONY: build 35 | build: $(BINARY_DIR) $(BINARIES) 36 | 37 | # Rule to build each binary 38 | $(BINARY_DIR)/%: cmd/% 39 | $(GOBUILD) -o $@ ./cmd/$* 40 | 41 | # Clean build artifacts 42 | .PHONY: clean 43 | clean: 44 | $(GOCLEAN) 45 | rm -rf $(BINARY_DIR) 46 | 47 | # List all commands 48 | .PHONY: list 49 | list: 50 | @echo "Available commands:" 51 | @echo $(CMD_DIRS) | tr ' ' '\n' 52 | -------------------------------------------------------------------------------- /rust/cluster_management/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dsql-examples" 3 | version = "0.1.0" 4 | edition = "2024" 5 | 6 | [dependencies] 7 | anyhow = "1.0.98" 8 | aws-config = "1.6.2" 9 | aws-sdk-dsql = "1.19.0" 10 | tokio = { version = "1", features = ["full"] } 11 | 12 | # Define each example as a separate binary. This ensures customers can easily execute individual examples without 13 | # modifying code or running the test suite. 14 | [[bin]] 15 | name = "create_single_region_cluster" 16 | path = "src/bin/create_single_region_cluster.rs" 17 | 18 | [[bin]] 19 | name = "create_multi_region_clusters" 20 | path = "src/bin/create_multi_region_clusters.rs" 21 | 22 | [[bin]] 23 | name = "get_cluster" 24 | path = "src/bin/get_cluster.rs" 25 | 26 | [[bin]] 27 | name = "update_cluster" 28 | path = "src/bin/update_cluster.rs" 29 | 30 | [[bin]] 31 | name = "delete_single_region_cluster" 32 | path = "src/bin/delete_single_region_cluster.rs" 33 | 34 | [[bin]] 35 | name = "delete_multi_region_clusters" 36 | path = "src/bin/delete_multi_region_clusters.rs" 37 | 38 | # Make example files available as libraries for testing 39 | [lib] 40 | name = "dsql_examples" 41 | path = "src/lib.rs" 42 | -------------------------------------------------------------------------------- /typescript/type-orm/src/entity/Vet.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | import { Column, Entity, PrimaryColumn, ManyToMany, JoinTable } from "typeorm"; 3 | import { Specialty } from "./Specialty"; 4 | import { v4 as uuidv4 } from "uuid"; 5 | 6 | @Entity("vet") 7 | export class Vet { 8 | @PrimaryColumn({ 9 | type: 'varchar', 10 | length: 36, 11 | generatedIdentity: "ALWAYS", 12 | default: "gen_random_uuid()" 13 | }) 14 | id: string; 15 | 16 | @Column({ 17 | length: 30, 18 | nullable: false 19 | }) 20 | name: string; 21 | 22 | @ManyToMany(() => Specialty, (specialty) => specialty.vets, { 23 | cascade: true 24 | }) 25 | @JoinTable({ 26 | name: "vet_specialty", 27 | joinColumn: { 28 | name: "vet_id", 29 | referencedColumnName: "id" 30 | }, 31 | inverseJoinColumn: { 32 | name: "specialty_name", 33 | referencedColumnName: "name" 34 | } 35 | }) 36 | specialties: Specialty[]; 37 | 38 | constructor() { 39 | if (!this.id) { 40 | this.id = uuidv4(); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /go/cluster_management/cmd/create_single_region/create_single_region_integ_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | var ( 12 | testCtx context.Context 13 | cancel context.CancelFunc 14 | ) 15 | 16 | func TestMain(m *testing.M) { 17 | setup() 18 | code := m.Run() 19 | teardown() 20 | os.Exit(code) 21 | } 22 | 23 | func setup() { 24 | testCtx, cancel = context.WithTimeout(context.Background(), 10*time.Minute) 25 | } 26 | 27 | func teardown() { 28 | cancel() 29 | } 30 | 31 | // Test for CreateSingleRegionCluster function 32 | func TestCreateSingleRegionCluster(t *testing.T) { 33 | tests := []struct { 34 | name string 35 | region1 string 36 | region2 string 37 | wantErr bool 38 | }{ 39 | { 40 | name: "Create single-region cluster", 41 | region1: "us-east-1", 42 | wantErr: false, 43 | }, 44 | } 45 | 46 | for _, tt := range tests { 47 | t.Run(tt.name, func(t *testing.T) { 48 | err := CreateCluster(testCtx, tt.region1) 49 | if err != nil { 50 | fmt.Printf("failed to create multi-region clusters: %v", err) 51 | panic(err) 52 | } 53 | }) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /dotnet/cluster_management/examples/GetCluster/GetCluster.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | DSQLExamples.GetCluster 4 | Library 5 | 6 | 7 | netstandard2.0;net9.0 8 | 10 9 | 10 | enable 11 | enable 12 | false 13 | false 14 | 15 | 16 | 18 | 19 | Exe 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /dotnet/cluster_management/examples/UpdateCluster/UpdateCluster.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | DSQLExamples.UpdateCluster 4 | Library 5 | 6 | 7 | netstandard2.0;net9.0 8 | 10 9 | 10 | enable 11 | enable 12 | false 13 | false 14 | 15 | 16 | 18 | 19 | Exe 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/initializers/content_security_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide content security policy. 4 | # See the Securing Rails Applications Guide for more information: 5 | # https://guides.rubyonrails.org/security.html#content-security-policy-header 6 | 7 | # Rails.application.configure do 8 | # config.content_security_policy do |policy| 9 | # policy.default_src :self, :https 10 | # policy.font_src :self, :https, :data 11 | # policy.img_src :self, :https, :data 12 | # policy.object_src :none 13 | # policy.script_src :self, :https 14 | # policy.style_src :self, :https 15 | # # Specify URI for violation reports 16 | # # policy.report_uri "/csp-violation-report-endpoint" 17 | # end 18 | # 19 | # # Generate session nonces for permitted importmap, inline scripts, and inline styles. 20 | # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } 21 | # config.content_security_policy_nonce_directives = %w(script-src style-src) 22 | # 23 | # # Report violations without enforcing the policy. 24 | # # config.content_security_policy_report_only = true 25 | # end 26 | -------------------------------------------------------------------------------- /go/cluster_management/cmd/create_multi_region/create_multi_region_integ_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | var ( 12 | testCtx context.Context 13 | cancel context.CancelFunc 14 | ) 15 | 16 | func TestMain(m *testing.M) { 17 | setup() 18 | code := m.Run() 19 | teardown() 20 | os.Exit(code) 21 | } 22 | 23 | func setup() { 24 | testCtx, cancel = context.WithTimeout(context.Background(), 10*time.Minute) 25 | } 26 | 27 | func teardown() { 28 | cancel() 29 | } 30 | 31 | // Test for CreateMultiRegionCluster function 32 | func TestCreateMultiRegionCluster(t *testing.T) { 33 | tests := []struct { 34 | name string 35 | region1 string 36 | region2 string 37 | wantErr bool 38 | }{ 39 | { 40 | name: "Create multi-region clusters", 41 | region1: "us-east-1", 42 | region2: "us-east-2", 43 | wantErr: false, 44 | }, 45 | } 46 | 47 | for _, tt := range tests { 48 | t.Run(tt.name, func(t *testing.T) { 49 | err := CreateMultiRegionClusters(testCtx, "us-west-2", tt.region1, tt.region2) 50 | if err != nil { 51 | fmt.Printf("failed to create multi-region clusters: %v", err) 52 | panic(err) 53 | } 54 | }) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /dotnet/cluster_management/examples/CreateMultiRegionClusters/CreateMultiRegionClusters.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | DSQLExamples.CreateMultiRegionClusters 4 | Library 5 | 6 | 7 | netstandard2.0;net9.0 8 | 10 9 | 10 | enable 11 | enable 12 | false 13 | false 14 | 15 | 16 | 18 | 19 | Exe 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /dotnet/cluster_management/examples/CreateSingleRegionCluster/CreateSingleRegionCluster.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | DSQLExamples.CreateSingleRegionCluster 4 | Library 5 | 6 | 7 | netstandard2.0;net9.0 8 | 10 9 | 10 | enable 11 | enable 12 | false 13 | false 14 | 15 | 16 | 18 | 19 | Exe 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /dotnet/cluster_management/examples/DeleteMultiRegionClusters/DeleteMultiRegionClusters.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | DSQLExamples.DeleteMultiRegionClusters 4 | Library 5 | 6 | 7 | netstandard2.0;net9.0 8 | 10 9 | 10 | enable 11 | enable 12 | false 13 | false 14 | 15 | 16 | 18 | 19 | Exe 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /dotnet/cluster_management/examples/DeleteSingleRegionCluster/DeleteSingleRegionCluster.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | DSQLExamples.DeleteSingleRegionCluster 4 | Library 5 | 6 | 7 | netstandard2.0;net9.0 8 | 10 9 | 10 | enable 11 | enable 12 | false 13 | false 14 | 15 | 16 | 18 | 19 | Exe 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "fileutils" 3 | 4 | APP_ROOT = File.expand_path("..", __dir__) 5 | APP_NAME = "petclinic" 6 | 7 | def system!(*args) 8 | system(*args, exception: true) 9 | end 10 | 11 | FileUtils.chdir APP_ROOT do 12 | # This script is a way to set up or update your development environment automatically. 13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome. 14 | # Add necessary setup steps to this file. 15 | 16 | puts "== Installing dependencies ==" 17 | system! "gem install bundler --conservative" 18 | system("bundle check") || system!("bundle install") 19 | 20 | # puts "\n== Copying sample files ==" 21 | # unless File.exist?("config/database.yml") 22 | # FileUtils.cp "config/database.yml.sample", "config/database.yml" 23 | # end 24 | 25 | puts "\n== Preparing database ==" 26 | system! "bin/rails db:prepare" 27 | 28 | puts "\n== Removing old logs and tempfiles ==" 29 | system! "bin/rails log:clear tmp:clear" 30 | 31 | puts "\n== Restarting application server ==" 32 | system! "bin/rails restart" 33 | 34 | # puts "\n== Configuring puma-dev ==" 35 | # system "ln -nfs #{APP_ROOT} ~/.puma-dev/#{APP_NAME}" 36 | # system "curl -Is https://#{APP_NAME}.test/up | head -n 1" 37 | end 38 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/storage.yml: -------------------------------------------------------------------------------- 1 | test: 2 | service: Disk 3 | root: <%= Rails.root.join("tmp/storage") %> 4 | 5 | local: 6 | service: Disk 7 | root: <%= Rails.root.join("storage") %> 8 | 9 | # Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) 10 | # amazon: 11 | # service: S3 12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> 13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> 14 | # region: us-east-1 15 | # bucket: your_own_bucket-<%= Rails.env %> 16 | 17 | # Remember not to checkin your GCS keyfile to a repository 18 | # google: 19 | # service: GCS 20 | # project: your_project 21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> 22 | # bucket: your_own_bucket-<%= Rails.env %> 23 | 24 | # Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) 25 | # microsoft: 26 | # service: AzureStorage 27 | # storage_account_name: your_account_name 28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> 29 | # container: your_container_name-<%= Rails.env %> 30 | 31 | # mirror: 32 | # service: Mirror 33 | # primary: local 34 | # mirrors: [ amazon, google, microsoft ] 35 | -------------------------------------------------------------------------------- /java/cluster_management/src/main/java/org/example/GetCluster.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import java.util.Optional; 4 | 5 | import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; 6 | import software.amazon.awssdk.regions.Region; 7 | import software.amazon.awssdk.services.dsql.DsqlClient; 8 | import software.amazon.awssdk.services.dsql.model.GetClusterResponse; 9 | 10 | public class GetCluster { 11 | 12 | public static void main(String[] args) { 13 | Region region = Region.of(System.getenv().getOrDefault("CLUSTER_REGION", "us-east-1")); 14 | String clusterId = Optional.ofNullable(System.getenv("CLUSTER_ID")) 15 | .orElseThrow(() -> new IllegalStateException("Expected CLUSTER_ID in environment")); 16 | 17 | try ( 18 | DsqlClient client = DsqlClient.builder() 19 | .region(region) 20 | .credentialsProvider(DefaultCredentialsProvider.create()) 21 | .build() 22 | ) { 23 | GetClusterResponse cluster = client.getCluster(r -> r.identifier(clusterId)); 24 | System.out.println(cluster); 25 | } 26 | } 27 | 28 | public static GetClusterResponse example(DsqlClient client, String clusterId) { 29 | return client.getCluster(r -> r.identifier(clusterId)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /typescript/prisma/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prisma-example", 3 | "version": "1.0.0", 4 | "main": "dist/index.js", 5 | "scripts": { 6 | "prisma:generate": "npx prisma generate --schema=prisma/veterinary-schema.prisma", 7 | "prisma:migrate-up": "PRISMA_SCHEMA_DISABLE_ADVISORY_LOCK=1 npx prisma migrate deploy --schema=prisma/veterinary-schema.prisma", 8 | "prisma:migrate-down": "npx prisma db execute --file prisma/migrations/0_init/down.sql --schema prisma/veterinary-schema.prisma", 9 | "format": "prettier --write .", 10 | "format:check": "prettier --check .", 11 | "prebuild": "npm run prisma:generate", 12 | "build": "tsc", 13 | "presample": "npm run build", 14 | "sample": "tsx src/index.ts", 15 | "pretest": "npm run build", 16 | "test": "jest" 17 | }, 18 | "devDependencies": { 19 | "@types/jest": "^30.0.0", 20 | "@types/node": "^24.1.0", 21 | "prettier": "^3.6.2", 22 | "prisma": "^6.12.0", 23 | "ts-jest": "^29.4.1", 24 | "tsx": "^4.20.3", 25 | "typescript": "^5.8.3" 26 | }, 27 | "dependencies": { 28 | "@aws-sdk/dsql-signer": "^3.848.0", 29 | "@prisma/adapter-pg": "^6.14.0", 30 | "@prisma/client": "^6.12.0", 31 | "@types/pg": "^8.15.5", 32 | "pg": "^8.16.3" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /typescript/prisma/prisma/veterinary-schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client" 3 | output = "../generated/prisma-vet" 4 | previewFeatures = ["driverAdapters"] 5 | } 6 | 7 | datasource db { 8 | provider = "postgresql" 9 | url = env("DATABASE_URL") 10 | relationMode = "prisma" 11 | } 12 | 13 | model SpecialtyToVet { 14 | A String @db.VarChar(80) 15 | B String @db.Uuid 16 | 17 | @@id([A, B]) 18 | @@map("_SpecialtyToVet") 19 | } 20 | 21 | model owner { 22 | id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid 23 | name String @db.VarChar(30) 24 | city String @db.VarChar(80) 25 | telephone String? @db.VarChar(20) 26 | pets pet[] 27 | } 28 | 29 | model pet { 30 | id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid 31 | name String @db.VarChar(30) 32 | birthDate DateTime @db.Date 33 | ownerId String? @db.Uuid 34 | owner owner? @relation(fields: [ownerId], references: [id]) 35 | 36 | @@index([ownerId]) 37 | } 38 | 39 | model specialty { 40 | name String @id @db.VarChar(80) 41 | vets vet[] @relation("SpecialtyToVet") 42 | } 43 | 44 | model vet { 45 | id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid 46 | name String @db.VarChar(30) 47 | specialties specialty[] @relation("SpecialtyToVet") 48 | } 49 | -------------------------------------------------------------------------------- /rust/cluster_management/tests/single_region_test.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | #[cfg(test)] 4 | mod tests { 5 | use super::*; 6 | use aws_sdk_dsql::types::ClusterStatus; 7 | use dsql_examples::create_single_region_cluster::create_cluster; 8 | use dsql_examples::delete_single_region_cluster::delete_cluster; 9 | use dsql_examples::get_cluster::get_cluster; 10 | use dsql_examples::update_cluster::update_cluster; 11 | 12 | #[tokio::test] 13 | async fn test_single_region_cluster_lifecycle() -> anyhow::Result<()> { 14 | let region = env::var("CLUSTER_REGION").unwrap_or(String::from("us-east-1")); 15 | 16 | println!("Creating single region cluster..."); 17 | let output = create_cluster(®ion).await?; 18 | let cluster_id = output.identifier; 19 | 20 | println!("Getting cluster details..."); 21 | let cluster = get_cluster(®ion, &cluster_id).await?; 22 | assert_eq!(cluster.status, ClusterStatus::Active); 23 | 24 | println!("Updating cluster to remove deletion protection..."); 25 | let update_response = update_cluster(®ion, &cluster_id).await?; 26 | assert_eq!(update_response.status, ClusterStatus::Updating); 27 | 28 | println!("Deleting cluster..."); 29 | delete_cluster(®ion, &cluster_id).await?; 30 | 31 | println!("Single region cluster test completed successfully"); 32 | Ok(()) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /typescript/type-orm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "type-orm", 3 | "version": "1.0.0", 4 | "description": "How-to", 5 | "main": "index.js", 6 | "scripts": { 7 | "migrations-create-table": "node dist/src/create-migrations-table.js", 8 | "migrations-drop-table": "node dist/src/drop-migrations-table.js", 9 | "migrations-run": "npm run typeorm migration:run -- -d ./dist/src/data-source --transaction none", 10 | "migrations-revert": "npm run typeorm migration:revert -- -d ./dist/src/data-source --transaction none", 11 | "build:compile": "tsc --build", 12 | "build": "npm-run-all build:compile", 13 | "clean": "rm -rf build && rm -rf dist", 14 | "typeorm": "ts-node ./node_modules/typeorm/cli.js", 15 | "start": "node dist/index.js", 16 | "dev": "npm run clean && npm run build && npm run start", 17 | "test": "npm run clean && npm run build && jest dist/test" 18 | }, 19 | "author": "", 20 | "license": "ISC", 21 | "devDependencies": { 22 | "@types/jest": "^29.5.14", 23 | "@types/node": "^22.9.0", 24 | "jest": "^29.7.0", 25 | "reflect-metadata": "^0.2.2", 26 | "typescript": "^5.6.3" 27 | }, 28 | "dependencies": { 29 | "@aws-sdk/dsql-signer": "^3.705.0", 30 | "assert": "^2.1.0", 31 | "npm-run-all": "^4.1.5", 32 | "pg": "^8.13.1", 33 | "ts-node": "^10.9.2", 34 | "typeorm": "^0.3.26", 35 | "uuid": "^11.0.3" 36 | }, 37 | "engines": { 38 | "node": ">=18.0.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cpp/libpq/src/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for libpq samples 3 | # 4 | 5 | # Common 6 | AWS_INC_DIR=-I ../aws-sdk-install/include 7 | AWS_LIB_DIR=-L ../aws-sdk-install/lib 8 | 9 | LIBS=-lpq -laws-cpp-sdk-dsql -laws-cpp-sdk-core 10 | 11 | # Linux 12 | PG_INC_DIR=-I /usr/local/pgsql/include 13 | LIBPQ_DIR=-L /usr/local/pgsql/lib 14 | 15 | INC_DIR=$(PG_INC_DIR) $(AWS_INC_DIR) 16 | LIB_DIR=$(LIBPQ_DIR) $(AWS_LIB_DIR) 17 | 18 | # Ubuntu 19 | PG_INC_DIR_UBUNTU=-I /usr/include/postgresql 20 | LIBPQ_DIR_UBUNTU=-L /lib/x86_64-linux-gnu/ 21 | 22 | INC_DIR_UBUNTU=$(PG_INC_DIR_UBUNTU) $(AWS_INC_DIR) 23 | LIB_DIR_UBUNTU=$(LIBPQ_DIR_UBUNTU) $(AWS_LIB_DIR) 24 | 25 | # Mac 26 | COMPILER_INC_DIR_MAC=-I /Library/Developer/CommandLineTools/SDKs/MacOSX14.5.sdk/usr/include/c++/v1 27 | PG_INC_DIR_MAC=-I /usr/local/opt/libpq/include 28 | LIBPQ_DIR_MAC=-L /usr/local/opt/libpq/lib 29 | 30 | INC_DIR_MAC=$(COMPILER_INC_DIR_MAC) $(PG_INC_DIR_MAC) $(AWS_INC_DIR) 31 | LIB_DIR_MAC=$(LIBPQ_DIR_MAC) $(AWS_LIB_DIR) 32 | 33 | 34 | libpq_example: libpq_example.cpp 35 | g++ libpq_example.cpp -o libpq_example $(INC_DIR) $(LIB_DIR) $(LIBS) 36 | 37 | libpq_example_ubuntu: libpq_example.cpp 38 | g++ libpq_example.cpp -o libpq_example $(INC_DIR_UBUNTU) $(LIB_DIR_UBUNTU) $(LIBS) 39 | 40 | libpq_example_mac: libpq_example.cpp 41 | g++ -std=c++11 libpq_example.cpp -o libpq_example $(INC_DIR_MAC) $(LIB_DIR_MAC) $(LIBS) 42 | 43 | clean: 44 | rm -f libpq_example 45 | -------------------------------------------------------------------------------- /.github/workflows/clean-clusters.yml: -------------------------------------------------------------------------------- 1 | name: Clean up Aurora DSQL Clusters 2 | 3 | permissions: {} 4 | 5 | on: 6 | workflow_call: 7 | inputs: 8 | aws_region: 9 | required: false 10 | type: string 11 | default: 'us-east-1' 12 | description: 'Default AWS region for credentials, does not limit access to other regions' 13 | secrets: 14 | AWS_IAM_ROLE: 15 | required: true 16 | description: 'AWS IAM role to assume for cluster cleanup' 17 | 18 | jobs: 19 | cleanup: 20 | name: Clean up Aurora DSQL Clusters 21 | runs-on: ubuntu-latest 22 | timeout-minutes: 10 23 | permissions: 24 | id-token: write # required by aws-actions/configure-aws-credentials 25 | 26 | steps: 27 | - name: Checkout code 28 | uses: actions/checkout@v4 29 | 30 | - name: Update AWS CLI to latest version 31 | run: | 32 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 33 | unzip -q awscliv2.zip 34 | sudo ./aws/install --update 35 | aws --version 36 | 37 | - name: Configure AWS Credentials 38 | uses: aws-actions/configure-aws-credentials@v4 39 | with: 40 | role-to-assume: ${{ secrets.AWS_IAM_ROLE }} 41 | aws-region: ${{ inputs.aws_region }} 42 | 43 | - name: Run cluster cleanup script 44 | env: 45 | IS_CI: "true" 46 | run: .github/scripts/clean-clusters.sh 47 | -------------------------------------------------------------------------------- /java/cluster_management/src/main/java/org/example/UpdateCluster.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import java.util.Optional; 4 | 5 | import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; 6 | import software.amazon.awssdk.regions.Region; 7 | import software.amazon.awssdk.services.dsql.DsqlClient; 8 | import software.amazon.awssdk.services.dsql.model.UpdateClusterResponse; 9 | 10 | public class UpdateCluster { 11 | 12 | public static void main(String[] args) { 13 | Region region = Region.of(System.getenv().getOrDefault("CLUSTER_REGION", "us-east-1")); 14 | String clusterId = Optional.ofNullable(System.getenv("CLUSTER_ID")) 15 | .orElseThrow(() -> new IllegalStateException("Expected CLUSTER_ID in environment")); 16 | 17 | try ( 18 | DsqlClient client = DsqlClient.builder() 19 | .region(region) 20 | .credentialsProvider(DefaultCredentialsProvider.create()) 21 | .build() 22 | ) { 23 | UpdateClusterResponse cluster = example(client, clusterId, false); 24 | System.out.println("Updated " + cluster.arn()); 25 | } 26 | } 27 | 28 | public static UpdateClusterResponse example( 29 | DsqlClient client, 30 | String clusterId, 31 | boolean setDeletionProtection) { 32 | return client.updateCluster(r -> r.identifier(clusterId).deletionProtectionEnabled(setDeletionProtection)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /go/cluster_management/cmd/get_cluster/get_cluster_integ.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "example/internal/util" 6 | "log" 7 | "os" 8 | "time" 9 | 10 | "github.com/aws/aws-sdk-go-v2/aws" 11 | "github.com/aws/aws-sdk-go-v2/config" 12 | 13 | "github.com/aws/aws-sdk-go-v2/service/dsql" 14 | ) 15 | 16 | func GetCluster(ctx context.Context, region, identifier string) (clusterStatus *dsql.GetClusterOutput, err error) { 17 | 18 | cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region)) 19 | if err != nil { 20 | log.Fatalf("Failed to load AWS configuration: %v", err) 21 | } 22 | 23 | // Initialize the DSQL client 24 | client := dsql.NewFromConfig(cfg) 25 | 26 | input := &dsql.GetClusterInput{ 27 | Identifier: aws.String(identifier), 28 | } 29 | clusterStatus, err = client.GetCluster(context.Background(), input) 30 | 31 | if err != nil { 32 | log.Fatalf("Failed to get cluster: %v", err) 33 | } 34 | 35 | log.Printf("Cluster ARN: %s", *clusterStatus.Arn) 36 | 37 | return clusterStatus, nil 38 | } 39 | 40 | func main() { 41 | ctx, cancel := context.WithTimeout(context.Background(), 6*time.Minute) 42 | defer cancel() 43 | 44 | identifier := os.Getenv("CLUSTER_ID") 45 | if identifier == "" { 46 | log.Fatal("CLUSTER_ID environment variable is not set") 47 | } 48 | 49 | region := util.GetEnvWithDefault("CLUSTER_REGION", "us-east-1") 50 | 51 | _, err := GetCluster(ctx, region, identifier) 52 | if err != nil { 53 | log.Fatalf("Failed to get cluster: %v", err) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /typescript/type-orm/src/drop-migrations-table.ts: -------------------------------------------------------------------------------- 1 | import { DsqlSigner } from "@aws-sdk/dsql-signer"; 2 | import { Client } from "pg"; 3 | import { getEnvironmentVariables } from "./utils"; 4 | import fs from "fs"; 5 | import path from "path"; 6 | 7 | const dropMigrationsTable = async () => { 8 | const { user, clusterEndpoint, region } = getEnvironmentVariables(); 9 | 10 | const signer = new DsqlSigner({ 11 | hostname: clusterEndpoint, 12 | region: region, 13 | }); 14 | 15 | let token: string; 16 | let schema = "public"; 17 | let client: Client | undefined; 18 | 19 | try { 20 | if (user === "admin") { 21 | token = await signer.getDbConnectAdminAuthToken(); 22 | } else { 23 | token = await signer.getDbConnectAuthToken(); 24 | schema = "myschema"; 25 | } 26 | 27 | client = new Client({ 28 | user: user, 29 | password: token, 30 | host: clusterEndpoint, 31 | port: 5432, 32 | database: "postgres", 33 | ssl: { 34 | rejectUnauthorized: true, 35 | }, 36 | }); 37 | 38 | await client.connect(); 39 | await client.query( 40 | `DROP TABLE IF EXISTS ${client.escapeIdentifier(schema)}."migrations"` 41 | ); 42 | console.log(`Dropped the migration table from ${schema}`); 43 | } catch (error) { 44 | console.error("Failed to drop the migration table:", error); 45 | throw error; 46 | } finally { 47 | if (client) { 48 | await client.end(); 49 | } 50 | } 51 | }; 52 | 53 | dropMigrationsTable(); 54 | -------------------------------------------------------------------------------- /java/spring_boot/src/main/java/org/example/DatabaseService.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import org.springframework.jdbc.core.JdbcTemplate; 4 | import org.springframework.stereotype.Service; 5 | 6 | @Service 7 | public class DatabaseService { 8 | 9 | private final JdbcTemplate jdbcTemplate; 10 | 11 | public DatabaseService(final JdbcTemplate jdbcTemplate) { 12 | this.jdbcTemplate = jdbcTemplate; 13 | } 14 | 15 | public void testConnection() { 16 | jdbcTemplate.execute(""" 17 | CREATE TABLE IF NOT EXISTS owner ( 18 | id uuid NOT NULL DEFAULT gen_random_uuid(), 19 | name varchar(30) NOT NULL, 20 | city varchar(80) NOT NULL, 21 | telephone varchar(20) DEFAULT NULL, 22 | PRIMARY KEY (id) 23 | )"""); 24 | 25 | jdbcTemplate.update( 26 | "INSERT INTO owner (name, city, telephone) VALUES (?, ?, ?)", 27 | "John Doe", "Anytown", "555-555-1999"); 28 | 29 | jdbcTemplate.query("SELECT * FROM owner", rs -> { 30 | while (rs.next()) { 31 | assert rs.getString("id") != null; 32 | assert rs.getString("name").equals("John Doe"); 33 | assert rs.getString("city").equals("Anytown"); 34 | assert rs.getString("telephone").equals("555-555-1999"); 35 | } 36 | }); 37 | 38 | jdbcTemplate.update("DELETE FROM owner WHERE name = ?", "John Doe"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /javascript/cluster_management/src/create_single_region_cluster.js: -------------------------------------------------------------------------------- 1 | import { DSQLClient, CreateClusterCommand, waitUntilClusterActive } from "@aws-sdk/client-dsql"; 2 | 3 | export async function createCluster(region) { 4 | 5 | const client = new DSQLClient({ region }); 6 | 7 | try { 8 | const createClusterCommand = new CreateClusterCommand({ 9 | deletionProtectionEnabled: true, 10 | tags: { 11 | Name: "javascript single region cluster", 12 | Repo: "aws-samples/aurora-dsql-samples" 13 | }, 14 | }); 15 | const response = await client.send(createClusterCommand); 16 | 17 | console.log(`Waiting for cluster ${response.identifier} to become ACTIVE`); 18 | await waitUntilClusterActive( 19 | { 20 | client: client, 21 | maxWaitTime: 300 // Wait for 5 minutes 22 | }, 23 | { 24 | identifier: response.identifier 25 | } 26 | ); 27 | console.log(`Cluster Id ${response.identifier} is now active`); 28 | return response; 29 | } catch (error) { 30 | console.error(`Unable to create cluster in ${region}: `, error.message); 31 | throw error; 32 | } 33 | } 34 | 35 | async function main() { 36 | const region = process.env.CLUSTER_REGION || "us-east-1"; 37 | const cluster = await createCluster(region); 38 | console.log(`Created ${cluster}`); 39 | } 40 | 41 | if (process.env.NODE_ENV !== 'test') { 42 | main(); 43 | } 44 | -------------------------------------------------------------------------------- /javascript/cluster_management/src/delete_single_region_cluster.js: -------------------------------------------------------------------------------- 1 | import { DSQLClient, DeleteClusterCommand, waitUntilClusterNotExists } from "@aws-sdk/client-dsql"; 2 | 3 | export async function deleteCluster(region, clusterId) { 4 | 5 | const client = new DSQLClient({ region }); 6 | 7 | try { 8 | const deleteClusterCommand = new DeleteClusterCommand({ 9 | identifier: clusterId, 10 | }); 11 | const response = await client.send(deleteClusterCommand); 12 | 13 | console.log(`Waiting for cluster ${response.identifier} to finish deletion`); 14 | 15 | await waitUntilClusterNotExists( 16 | { 17 | client: client, 18 | maxWaitTime: 300 // Wait for 5 minutes 19 | }, 20 | { 21 | identifier: response.identifier 22 | } 23 | ); 24 | console.log(`Cluster Id ${response.identifier} is now deleted`); 25 | return; 26 | } catch (error) { 27 | if (error.name === "ResourceNotFoundException") { 28 | console.log("Cluster ID not found or already deleted"); 29 | } else { 30 | console.error("Unable to delete cluster: ", error.message); 31 | } 32 | throw error; 33 | } 34 | } 35 | 36 | async function main() { 37 | const region = process.env.CLUSTER_REGION || "us-east-1"; 38 | const clusterId = process.env.CLUSTER_ID; 39 | 40 | if (!clusterId) { 41 | console.error("Error: CLUSTER_ID environment variables must be set"); 42 | process.exit(1); 43 | } 44 | 45 | await deleteCluster(region, clusterId); 46 | } 47 | 48 | if (process.env.NODE_ENV !== 'test') { 49 | main(); 50 | } 51 | -------------------------------------------------------------------------------- /dotnet/cluster_management/tests/DsqlExamples.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0 4 | 10 5 | 6 | enable 7 | enable 8 | false 9 | true 10 | false 11 | false 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.github/workflows/go-pgx-integ-tests.yml: -------------------------------------------------------------------------------- 1 | name: Go pgx integration tests 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [ "main" ] 8 | paths: 9 | - 'go/pgx/**' 10 | - '.github/workflows/go-pgx-integ-tests.yml' 11 | pull_request: 12 | branches: [ "main" ] 13 | paths: 14 | - 'go/pgx/**' 15 | - '.github/workflows/go-pgx-integ-tests.yml' 16 | # Give us a button to allow running the workflow on demand for testing. 17 | workflow_dispatch: 18 | inputs: 19 | tags: 20 | description: 'Manual Workflow Run' 21 | required: false 22 | type: string 23 | 24 | jobs: 25 | 26 | build: 27 | runs-on: ubuntu-latest 28 | permissions: 29 | id-token: write # required by aws-actions/configure-aws-credentials 30 | concurrency: 31 | # Ensure only 1 job uses the workflow cluster at a time. 32 | group: ${{ github.workflow }} 33 | env: 34 | GOPROXY: direct 35 | 36 | steps: 37 | - uses: actions/checkout@v4 38 | 39 | - name: Set up Go 40 | uses: actions/setup-go@v4 41 | with: 42 | go-version: '1.23.2' 43 | 44 | - name: Configure AWS Credentials 45 | uses: aws-actions/configure-aws-credentials@v4 46 | with: 47 | role-to-assume: ${{ secrets.GO_IAM_ROLE }} 48 | aws-region: us-east-1 49 | 50 | - name: Build & Run 51 | working-directory: ./go/pgx 52 | env: 53 | CLUSTER_USER: "admin" 54 | CLUSTER_ENDPOINT: ${{ secrets.GO_PGX_CLUSTER_ENDPOINT }} 55 | REGION: ${{ secrets.GO_PGX_CLUSTER_REGION }} 56 | run: | 57 | go test -v 58 | -------------------------------------------------------------------------------- /.github/workflows/rust-sqlx-integ-test.yml: -------------------------------------------------------------------------------- 1 | name: Rust SQLx integration Tests 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [ main ] 8 | paths: 9 | - 'rust/sqlx/**' 10 | - '.github/workflows/rust-sqlx-integ-test.yml' 11 | pull_request: 12 | branches: [ main ] 13 | paths: 14 | - 'rust/sqlx/**' 15 | - '.github/workflows/rust-sqlx-integ-test.yml' 16 | # Give us a button to allow running the workflow on demand for testing. 17 | workflow_dispatch: 18 | inputs: 19 | tags: 20 | description: 'Manual Workflow Run' 21 | required: false 22 | type: string 23 | 24 | jobs: 25 | test: 26 | runs-on: ubuntu-latest 27 | timeout-minutes: 15 28 | permissions: 29 | id-token: write # required by aws-actions/configure-aws-credentials 30 | concurrency: 31 | # Ensure only 1 job uses the workflow cluster at a time. 32 | group: ${{ github.workflow }} 33 | 34 | steps: 35 | - name: Checkout code 36 | uses: actions/checkout@v4 37 | 38 | - name: Set up Rust 39 | run: rustup update 40 | 41 | - name: Configure AWS Credentials 42 | uses: aws-actions/configure-aws-credentials@v4 43 | with: 44 | role-to-assume: ${{ secrets.RUST_IAM_ROLE }} 45 | aws-region: us-east-1 46 | 47 | - name: Configure and run integration tests for SQLx 48 | working-directory: ./rust/sqlx 49 | env: 50 | CLUSTER_USER: "admin" 51 | CLUSTER_ENDPOINT: ${{ secrets.RUST_SQLX_CLUSTER_ENDPOINT }} 52 | REGION: ${{ secrets.RUST_SQLX_CLUSTER_REGION }} 53 | run: | 54 | cargo run 55 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/initializers/adapter.rb: -------------------------------------------------------------------------------- 1 | PG::AWS_RDS_IAM.auth_token_generators.add :dsql do 2 | DsqlAuthTokenGenerator.new 3 | end 4 | 5 | require "aws-sdk-dsql" 6 | 7 | class DsqlAuthTokenGenerator 8 | def call(host:, port:, user:) 9 | # e.g. host == ".dsql.us-east-1.on.aws" 10 | region = host.split(".")[2] 11 | raise "Unable to extract AWS region from host '#{host}'" unless region =~ /[\w\d-]+/ 12 | 13 | token_generator = Aws::DSQL::AuthTokenGenerator.new( 14 | credentials: Aws::CredentialProviderChain.new.resolve, 15 | ) 16 | 17 | auth_token_params = { 18 | endpoint: host, 19 | region: region, 20 | expires_in: 15 * 60 # 15 minutes, optional 21 | } 22 | 23 | case user 24 | when "admin" 25 | token_generator.generate_db_connect_admin_auth_token(auth_token_params) 26 | else 27 | token_generator.generate_db_connect_auth_token(auth_token_params) 28 | end 29 | end 30 | end 31 | 32 | # Monkey-patches to disable unsupported features 33 | 34 | require "active_record/connection_adapters/postgresql/schema_statements" 35 | 36 | module ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements 37 | # DSQL does not support setting min_messages in the connection parameters 38 | def client_min_messages=(level); end 39 | end 40 | 41 | require "active_record/connection_adapters/postgresql_adapter" 42 | 43 | class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter 44 | def set_standard_conforming_strings; end 45 | 46 | # Avoid error running multiple DDL or DDL + DML statements in the same transaction 47 | def supports_ddl_transactions? 48 | false 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /go/cluster_management/cmd/update_cluster/update_cluster.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "example/internal/util" 6 | "log" 7 | "os" 8 | "time" 9 | 10 | "github.com/aws/aws-sdk-go-v2/config" 11 | 12 | "github.com/aws/aws-sdk-go-v2/service/dsql" 13 | ) 14 | 15 | func UpdateCluster(ctx context.Context, id, region string, deleteProtection bool) (clusterStatus *dsql.UpdateClusterOutput, err error) { 16 | 17 | cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region)) 18 | if err != nil { 19 | log.Fatalf("Failed to load AWS configuration: %v", err) 20 | } 21 | 22 | // Initialize the DSQL client 23 | client := dsql.NewFromConfig(cfg) 24 | 25 | input := dsql.UpdateClusterInput{ 26 | Identifier: &id, 27 | DeletionProtectionEnabled: &deleteProtection, 28 | } 29 | 30 | clusterStatus, err = client.UpdateCluster(context.Background(), &input) 31 | 32 | if err != nil { 33 | log.Fatalf("Failed to update cluster: %v", err) 34 | } 35 | 36 | log.Printf("Cluster updated successfully: %v", clusterStatus.Status) 37 | return clusterStatus, nil 38 | } 39 | 40 | func main() { 41 | ctx, cancel := context.WithTimeout(context.Background(), 6*time.Minute) 42 | defer cancel() 43 | 44 | deleteProtection := util.GetEnvWithDefault("DELETE_PROTECTION", "false") == "true" 45 | 46 | identifier := os.Getenv("CLUSTER_ID") 47 | if identifier == "" { 48 | log.Fatal("CLUSTER_ID environment variable is not set") 49 | } 50 | 51 | region := util.GetEnvWithDefault("CLUSTER_REGION", "us-east-1") 52 | 53 | _, err := UpdateCluster(ctx, identifier, region, deleteProtection) 54 | if err != nil { 55 | log.Fatalf("Failed to update cluster: %v", err) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /go/pgx/go.mod: -------------------------------------------------------------------------------- 1 | module pgx 2 | 3 | go 1.24.0 4 | 5 | require ( 6 | github.com/aws/aws-sdk-go-v2/config v1.29.14 7 | github.com/aws/aws-sdk-go-v2/feature/dsql/auth v1.0.1 8 | github.com/google/uuid v1.6.0 9 | github.com/jackc/pgx/v5 v5.7.5 10 | github.com/stretchr/testify v1.9.0 11 | ) 12 | 13 | require ( 14 | github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect 15 | github.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect 16 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect 17 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect 18 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect 19 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect 20 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect 21 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect 22 | github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect 23 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect 24 | github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect 25 | github.com/aws/smithy-go v1.22.2 // indirect 26 | github.com/davecgh/go-spew v1.1.1 // indirect 27 | github.com/jackc/pgpassfile v1.0.0 // indirect 28 | github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect 29 | github.com/jackc/puddle/v2 v2.2.2 // indirect 30 | github.com/kr/text v0.2.0 // indirect 31 | github.com/pmezard/go-difflib v1.0.0 // indirect 32 | github.com/rogpeppe/go-internal v1.14.1 // indirect 33 | golang.org/x/crypto v0.45.0 // indirect 34 | golang.org/x/sync v0.18.0 // indirect 35 | golang.org/x/text v0.31.0 // indirect 36 | gopkg.in/yaml.v3 v3.0.1 // indirect 37 | ) 38 | -------------------------------------------------------------------------------- /.github/workflows/dotnet-npgsql-integ-tests.yml: -------------------------------------------------------------------------------- 1 | name: Dotnet Npgsql integration tests 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [ "main" ] 8 | paths: 9 | - 'dotnet/npgsql/**' 10 | - '.github/workflows/dotnet-npgsql-integ-tests.yml' 11 | 12 | pull_request: 13 | branches: [ "main" ] 14 | paths: 15 | - 'dotnet/npgsql/**' 16 | - '.github/workflows/dotnet-npgsql-integ-tests.yml' 17 | 18 | # Give us a button to allow running the workflow on demand for testing. 19 | workflow_dispatch: 20 | inputs: 21 | tags: 22 | description: 'Manual Workflow Run' 23 | required: false 24 | type: string 25 | 26 | jobs: 27 | dotnet-npgsql-integ-test: 28 | runs-on: ubuntu-latest 29 | permissions: 30 | id-token: write # required by aws-actions/configure-aws-credentials 31 | concurrency: 32 | # Ensure only 1 job uses the workflow cluster at a time. 33 | group: ${{ github.workflow }} 34 | 35 | steps: 36 | - name: Checkout code 37 | uses: actions/checkout@v4 38 | 39 | - name: Setup .NET 40 | uses: actions/setup-dotnet@v3 41 | with: 42 | dotnet-version: '9.0.x' 43 | 44 | - name: Configure AWS Credentials 45 | uses: aws-actions/configure-aws-credentials@v4 46 | with: 47 | role-to-assume: ${{ secrets.DOTNET_IAM_ROLE }} 48 | aws-region: us-east-1 49 | 50 | - name: Configure and run integration for npgsql 51 | working-directory: ./dotnet/npgsql 52 | env: 53 | CLUSTER_USER: "admin" 54 | CLUSTER_ENDPOINT: ${{ secrets.DOTNET_NPGSQL_CLUSTER_ENDPOINT }} 55 | REGION: ${{ secrets.DOTNET_NPGSQL_CLUSTER_REGION }} 56 | run: | 57 | dotnet run --framework net9.0 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # macOS system files 2 | .DS_Store 3 | .DS_Store? 4 | ._* 5 | .Spotlight-V100 6 | .Trashes 7 | ehthumbs.db 8 | Thumbs.db 9 | 10 | # Maven build artifacts 11 | target/ 12 | pom.xml.tag 13 | pom.xml.releaseBackup 14 | pom.xml.versionsBackup 15 | pom.xml.next 16 | release.properties 17 | dependency-reduced-pom.xml 18 | buildNumber.properties 19 | .mvn/timing.properties 20 | .mvn/wrapper/maven-wrapper.jar 21 | 22 | # Gradle build artifacts 23 | .gradle/ 24 | build/ 25 | gradle-app.setting 26 | !gradle-wrapper.jar 27 | !gradle-wrapper.properties 28 | !gradle/wrapper/gradle-wrapper.jar 29 | !gradle/wrapper/gradle-wrapper.properties 30 | 31 | # IDE files 32 | .idea/ 33 | *.iws 34 | *.iml 35 | *.ipr 36 | .vscode/ 37 | .settings/ 38 | .project 39 | .classpath 40 | .factorypath 41 | 42 | # Java compiled classes 43 | *.class 44 | *.jar 45 | *.war 46 | *.ear 47 | *.nar 48 | hs_err_pid* 49 | replay_pid* 50 | 51 | # Logs 52 | *.log 53 | logs/ 54 | 55 | # Temporary files 56 | *.tmp 57 | *.temp 58 | *.swp 59 | *.swo 60 | *~ 61 | 62 | # Environment and configuration files (if they contain sensitive data) 63 | .env 64 | .env.local 65 | .env.*.local 66 | mise.toml 67 | root.pem 68 | 69 | # Test output 70 | TEST-*.xml 71 | *.txt 72 | 73 | # JVM crash logs 74 | hs_err_pid* 75 | 76 | # Package Files 77 | *.jar 78 | *.war 79 | *.nar 80 | *.ear 81 | *.zip 82 | *.tar.gz 83 | *.rar 84 | 85 | # virtual machine crash logs 86 | hs_err_pid* 87 | replay_pid* 88 | 89 | # Backup files 90 | *.bak 91 | *.backup 92 | *.orig 93 | 94 | # OS generated files 95 | Icon? 96 | .DocumentRevisions-V100 97 | .fseventsd 98 | .TemporaryItems 99 | .VolumeIcon.icns 100 | .com.apple.timemachine.donotpresent 101 | -------------------------------------------------------------------------------- /ruby/cluster_management/lib/delete_multi_region_clusters.rb: -------------------------------------------------------------------------------- 1 | require "aws-sdk-dsql" 2 | 3 | def delete_multi_region_clusters(region_1, cluster_id_1, region_2, cluster_id_2) 4 | client_1 = Aws::DSQL::Client.new(region: region_1) 5 | client_2 = Aws::DSQL::Client.new(region: region_2) 6 | 7 | puts "Deleting cluster #{cluster_id_1} in #{region_1}" 8 | client_1.delete_cluster(identifier: cluster_id_1) 9 | 10 | # cluster_1 will stay in PENDING_DELETE state until cluster_2 is deleted 11 | puts "Deleting #{cluster_id_2} in #{region_2}" 12 | client_2.delete_cluster(identifier: cluster_id_2) 13 | 14 | # Now that both clusters have been marked for deletion they will transition 15 | # to DELETING state and finalize deletion 16 | puts "Waiting for #{cluster_id_1} to finish deletion" 17 | client_1.wait_until(:cluster_not_exists, identifier: cluster_id_1) do |w| 18 | # Wait for 5 minutes 19 | w.max_attempts = 30 20 | w.delay = 10 21 | end 22 | 23 | puts "Waiting for #{cluster_id_2} to finish deletion" 24 | client_2.wait_until(:cluster_not_exists, identifier: cluster_id_2) do |w| 25 | # Wait for 5 minutes 26 | w.max_attempts = 30 27 | w.delay = 10 28 | end 29 | rescue Aws::Errors::ServiceError => e 30 | abort "Failed to delete multi-region clusters: #{e.message}" 31 | end 32 | 33 | def main 34 | region_1 = ENV.fetch("CLUSTER_1_REGION", "us-east-1") 35 | cluster_id_1 = ENV.fetch("CLUSTER_1_ID") 36 | region_2 = ENV.fetch("CLUSTER_2_REGION", "us-east-2") 37 | cluster_id_2 = ENV.fetch("CLUSTER_2_ID") 38 | 39 | delete_multi_region_clusters(region_1, cluster_id_1, region_2, cluster_id_2) 40 | puts "Deleted #{cluster_id_1} in #{region_1} and #{cluster_id_2} in #{region_2}" 41 | end 42 | 43 | main if $PROGRAM_NAME == __FILE__ 44 | -------------------------------------------------------------------------------- /go/cluster_management/cmd/delete_single_region/delete_single_cluster_integ_test.go: -------------------------------------------------------------------------------- 1 | // example_test.go 2 | package main 3 | 4 | import ( 5 | "context" 6 | "example/internal/util" 7 | "fmt" 8 | "os" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | var ( 14 | testCtx context.Context 15 | cancel context.CancelFunc 16 | ) 17 | 18 | func TestMain(m *testing.M) { 19 | setup() 20 | code := m.Run() 21 | teardown() 22 | os.Exit(code) 23 | } 24 | 25 | func setup() { 26 | // Initialize context with timeout for all tests 27 | testCtx, cancel = context.WithTimeout(context.Background(), 10*time.Minute) 28 | 29 | output, err := util.FindClusterWithTagAndRepository(testCtx, "us-east-1", "Name", util.GetUniqueRunTagName("go single region cluster")) 30 | 31 | if err != nil || output == nil || output.Identifier == nil { 32 | fmt.Errorf("Error finding cluster by tag") 33 | return 34 | } 35 | // Set up any environment variables needed for tests 36 | os.Setenv("CLUSTER_ID", *output.Identifier) 37 | } 38 | 39 | func teardown() { 40 | cancel() 41 | } 42 | 43 | // Test for DeleteSingleRegion function 44 | func TestDeleteSingleRegion(t *testing.T) { 45 | // Test cases 46 | tests := []struct { 47 | name string 48 | region string 49 | identifier string 50 | wantErr bool 51 | }{ 52 | { 53 | name: "Delete single-region cluster", 54 | region: "us-east-1", 55 | identifier: os.Getenv("CLUSTER_ID"), 56 | wantErr: false, 57 | }, 58 | } 59 | 60 | for _, tt := range tests { 61 | t.Run(tt.name, func(t *testing.T) { 62 | err := DeleteSingleRegion(testCtx, tt.identifier, tt.region) 63 | if (err != nil) != tt.wantErr { 64 | t.Errorf("DeleteSingleRegion() error = %v, wantErr %v", err, tt.wantErr) 65 | } 66 | }) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /typescript/type-orm/src/data-source.ts: -------------------------------------------------------------------------------- 1 | import "reflect-metadata"; 2 | import { DataSource } from "typeorm"; 3 | import { DsqlSigner } from "@aws-sdk/dsql-signer"; 4 | import path from "path"; 5 | import fs from "fs"; 6 | 7 | import { getEnvironmentVariables } from "./utils"; 8 | 9 | const getDataSource = async () => { 10 | const { user, clusterEndpoint, region } = getEnvironmentVariables(); 11 | 12 | const signer = new DsqlSigner({ 13 | hostname: clusterEndpoint, 14 | region: region, 15 | }); 16 | 17 | let schema: string = "public"; 18 | 19 | try { 20 | if (user !== "admin") { 21 | schema = "myschema"; 22 | } 23 | 24 | let AppDataSource = new DataSource({ 25 | type: "postgres", 26 | host: clusterEndpoint, 27 | port: 5432, 28 | username: user, 29 | password: () => user === "admin" 30 | ? signer.getDbConnectAdminAuthToken() 31 | : signer.getDbConnectAuthToken(), 32 | database: "postgres", 33 | ssl: { 34 | rejectUnauthorized: true, 35 | }, 36 | synchronize: false, 37 | logging: false, 38 | entities: [path.join(__dirname, "/entity/**/*{.ts,.js}")], 39 | schema: schema, 40 | migrations: [path.join(__dirname, "/migrations/**/*{.ts,.js}")], 41 | migrationsRun: false, 42 | // Pool options 43 | extra: { 44 | min: 0, 45 | max: 5, 46 | idleTimeoutMillis: 10000, 47 | connectionTimeoutMillis: 30000, 48 | maxLifetimeSeconds: 2700, // 45 min 49 | }, 50 | }); 51 | 52 | return AppDataSource; 53 | } catch (error) { 54 | console.error("Failed to initialize data source:", error); 55 | throw error; 56 | } 57 | }; 58 | 59 | export default getDataSource(); 60 | -------------------------------------------------------------------------------- /go/cluster_management/cmd/get_cluster/get_cluster_integ_test.go: -------------------------------------------------------------------------------- 1 | // example_test.go 2 | package main 3 | 4 | import ( 5 | "context" 6 | "example/internal/util" 7 | "fmt" 8 | "os" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | var ( 14 | testCtx context.Context 15 | cancel context.CancelFunc 16 | ) 17 | 18 | func TestMain(m *testing.M) { 19 | setup() 20 | code := m.Run() 21 | teardown() 22 | os.Exit(code) 23 | } 24 | 25 | func setup() { 26 | // Initialize context with timeout for all tests 27 | testCtx, cancel = context.WithTimeout(context.Background(), 10*time.Minute) 28 | 29 | output, err := util.FindClusterWithTagAndRepository(testCtx, "us-east-1", "Name", util.GetUniqueRunTagName("go single region cluster")) 30 | 31 | if err != nil || output == nil || output.Identifier == nil { 32 | fmt.Errorf("Error finding cluster by tag") 33 | return 34 | } 35 | 36 | // Set up any environment variables needed for tests 37 | os.Setenv("CLUSTER_REGION", "us-east-1") 38 | os.Setenv("CLUSTER_ID", *output.Identifier) 39 | } 40 | 41 | func teardown() { 42 | cancel() 43 | } 44 | 45 | // Test for GetCluster function 46 | func TestGetCluster(t *testing.T) { 47 | // Test cases 48 | tests := []struct { 49 | name string 50 | region string 51 | identifier string 52 | wantErr bool 53 | }{ 54 | { 55 | name: "Get cluster retrieval", 56 | region: os.Getenv("CLUSTER_REGION"), 57 | identifier: os.Getenv("CLUSTER_ID"), 58 | wantErr: false, 59 | }, 60 | } 61 | 62 | for _, tt := range tests { 63 | t.Run(tt.name, func(t *testing.T) { 64 | _, err := GetCluster(testCtx, tt.region, tt.identifier) 65 | if (err != nil) != tt.wantErr { 66 | t.Errorf("GetCluster() error = %v, wantErr %v", err, tt.wantErr) 67 | } 68 | }) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lambda/cdk.js: -------------------------------------------------------------------------------- 1 | import {App, aws_dsql, Stack, Duration} from 'aws-cdk-lib'; 2 | import {Code, Function, Runtime} from 'aws-cdk-lib/aws-lambda'; 3 | import {Effect, PolicyStatement} from "aws-cdk-lib/aws-iam"; 4 | 5 | const app = new App(); 6 | 7 | const region = process.env.CLUSTER_REGION || 'us-east-1'; 8 | 9 | class DsqlLambdaStack extends Stack { 10 | constructor(scope, id, props) { 11 | super(scope, id, props); 12 | 13 | const dsqlCluster = new aws_dsql.CfnCluster(this, 'DsqlCluster', { 14 | deletionProtectionEnabled: false, 15 | tags: [{ 16 | key: 'Name', value: 'Lambda single region cluster', 17 | }, { 18 | key: 'Repo', value: 'aws-samples/aurora-dsql-samples', 19 | }], 20 | }); 21 | 22 | // Define the Lambda function 23 | const dsqlFunction = new Function(this, 'DsqlLambdaSample', { 24 | functionName: 'DsqlLambdaSample', 25 | runtime: Runtime.NODEJS_22_X, 26 | handler: 'lambda.handler', 27 | code: Code.fromAsset('sample'), 28 | timeout: Duration.seconds(30), 29 | memorySize: 256, 30 | environment: { 31 | CLUSTER_ENDPOINT: `${dsqlCluster.attrIdentifier}.dsql.${region}.on.aws`, 32 | CLUSTER_REGION: region 33 | } 34 | }); 35 | 36 | // Add DSQL permissions to the Lambda function 37 | dsqlFunction.addToRolePolicy(new PolicyStatement({ 38 | effect: Effect.ALLOW, 39 | actions: ['dsql:DbConnectAdmin', 'dsql:DbConnect'], 40 | resources: [dsqlCluster.attrResourceArn] 41 | })); 42 | } 43 | } 44 | 45 | new DsqlLambdaStack(app, "DsqlSample", { 46 | env: { 47 | region: region 48 | } 49 | }) 50 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/config/puma.rb: -------------------------------------------------------------------------------- 1 | # This configuration file will be evaluated by Puma. The top-level methods that 2 | # are invoked here are part of Puma's configuration DSL. For more information 3 | # about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html. 4 | 5 | # Puma starts a configurable number of processes (workers) and each process 6 | # serves each request in a thread from an internal thread pool. 7 | # 8 | # The ideal number of threads per worker depends both on how much time the 9 | # application spends waiting for IO operations and on how much you wish to 10 | # to prioritize throughput over latency. 11 | # 12 | # As a rule of thumb, increasing the number of threads will increase how much 13 | # traffic a given process can handle (throughput), but due to CRuby's 14 | # Global VM Lock (GVL) it has diminishing returns and will degrade the 15 | # response time (latency) of the application. 16 | # 17 | # The default is set to 3 threads as it's deemed a decent compromise between 18 | # throughput and latency for the average Rails application. 19 | # 20 | # Any libraries that use a connection pool or another resource pool should 21 | # be configured to provide at least as many connections as the number of 22 | # threads. This includes Active Record's `pool` parameter in `database.yml`. 23 | threads_count = ENV.fetch("RAILS_MAX_THREADS", 3) 24 | threads threads_count, threads_count 25 | 26 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 27 | port ENV.fetch("PORT", 3000) 28 | 29 | # Allow puma to be restarted by `bin/rails restart` command. 30 | plugin :tmp_restart 31 | 32 | # Specify the PID file. Defaults to tmp/pids/server.pid in development. 33 | # In other environments, only set the PID file if requested. 34 | pidfile ENV["PIDFILE"] if ENV["PIDFILE"] 35 | -------------------------------------------------------------------------------- /.github/workflows/ruby-pg-integ-tests.yml: -------------------------------------------------------------------------------- 1 | name: Ruby pg integration tests 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [ main ] 8 | paths: 9 | - 'ruby/ruby-pg/**' 10 | - '.github/workflows/ruby-rubypg-integ-tests.yml' 11 | pull_request: 12 | branches: [ main ] 13 | paths: 14 | - 'ruby/ruby-pg/**' 15 | - '.github/workflows/ruby-rubypg-integ-tests.yml' 16 | # Give us a button to allow running the workflow on demand for testing. 17 | workflow_dispatch: 18 | inputs: 19 | tags: 20 | description: 'Manual Workflow Run' 21 | required: false 22 | type: string 23 | 24 | jobs: 25 | test: 26 | runs-on: ubuntu-latest 27 | permissions: 28 | id-token: write # required by aws-actions/configure-aws-credentials 29 | concurrency: 30 | # Ensure only 1 job uses the workflow cluster at a time. 31 | group: ${{ github.workflow }} 32 | 33 | steps: 34 | - name: Checkout code 35 | uses: actions/checkout@v4 36 | 37 | - name: Set up Ruby 3.3 38 | uses: ruby/setup-ruby@v1 39 | with: 40 | ruby-version: '3.3' 41 | bundler-cache: true 42 | 43 | - name: Configure AWS Credentials 44 | uses: aws-actions/configure-aws-credentials@v4 45 | with: 46 | role-to-assume: ${{ secrets.RUBY_IAM_ROLE }} 47 | aws-region: us-east-1 48 | 49 | - name: Configure and run integration for ruby-pg 50 | working-directory: ./ruby/ruby-pg 51 | env: 52 | CLUSTER_ENDPOINT: ${{ secrets.RUBY_RUBYPG_CLUSTER_ENDPOINT }} 53 | REGION: ${{ secrets.RUBY_RUBYPG_CLUSTER_REGION }} 54 | CLUSTER_USER: admin 55 | run: | 56 | bundle install 57 | wget https://www.amazontrust.com/repository/AmazonRootCA1.pem -O root.pem 58 | rspec 59 | -------------------------------------------------------------------------------- /.github/workflows/typescript-sequelize-integ-tests.yml: -------------------------------------------------------------------------------- 1 | name: TypeScript Sequelize integration tests 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [ "main" ] 8 | paths: 9 | - 'typescript/sequelize/**' 10 | - '.github/workflows/typescript-sequelize-integ-tests.yml' 11 | 12 | pull_request: 13 | branches: [ "main" ] 14 | paths: 15 | - 'typescript/sequelize/**' 16 | - '.github/workflows/typescript-sequelize-integ-tests.yml' 17 | 18 | # Give us a button to allow running the workflow on demand for testing. 19 | workflow_dispatch: 20 | inputs: 21 | tags: 22 | description: 'Manual Workflow Run' 23 | required: false 24 | type: string 25 | 26 | jobs: 27 | sequelize-integ-test: 28 | runs-on: ubuntu-latest 29 | permissions: 30 | id-token: write # required by aws-actions/configure-aws-credentials 31 | concurrency: 32 | # Ensure only 1 job uses the workflow cluster at a time. 33 | group: ${{ github.workflow }} 34 | 35 | steps: 36 | - name: Checkout code 37 | uses: actions/checkout@v4 38 | 39 | - name: Set up Node 40 | uses: actions/setup-node@v4 41 | with: 42 | node-version: '18.x' 43 | 44 | - name: Configure AWS Credentials 45 | uses: aws-actions/configure-aws-credentials@v4 46 | with: 47 | role-to-assume: ${{ secrets.TYPESCRIPT_IAM_ROLE }} 48 | aws-region: us-east-1 49 | 50 | - name: Configure and run integration for Sequelize 51 | working-directory: ./typescript/sequelize 52 | env: 53 | CLUSTER_ENDPOINT: ${{ secrets.TYPESCRIPT_SEQUELIZE_CLUSTER_ENDPOINT}} 54 | REGION: ${{ secrets.TYPESCRIPT_SEQUELIZE_CLUSTER_REGION}} 55 | CLUSTER_USER: 'admin' 56 | run: | 57 | npm ci 58 | npm run test 59 | -------------------------------------------------------------------------------- /.github/workflows/javascript-node-postgres-integ-tests.yml: -------------------------------------------------------------------------------- 1 | name: JavaScript node-postgres integration tests 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [ main ] 8 | paths: 9 | - 'javascript/node-postgres/**' 10 | - '.github/workflows/javascript-node-postgres-integ-tests.yml' 11 | pull_request: 12 | branches: [ main ] 13 | paths: 14 | - 'javascript/node-postgres/**' 15 | - '.github/workflows/javascript-node-postgres-integ-tests.yml' 16 | # Give us a button to allow running the workflow on demand for testing. 17 | workflow_dispatch: 18 | inputs: 19 | tags: 20 | description: 'Manual Workflow Run' 21 | required: false 22 | type: string 23 | 24 | jobs: 25 | node-postgres-integ-test: 26 | runs-on: ubuntu-latest 27 | permissions: 28 | id-token: write # required by aws-actions/configure-aws-credentials 29 | concurrency: 30 | # Ensure only 1 job uses the workflow cluster at a time. 31 | group: ${{ github.workflow }} 32 | 33 | steps: 34 | - name: Checkout code 35 | uses: actions/checkout@v4 36 | 37 | - name: Set up Node 38 | uses: actions/setup-node@v4 39 | with: 40 | node-version: '18.x' 41 | 42 | - name: Configure AWS Credentials 43 | uses: aws-actions/configure-aws-credentials@v4 44 | with: 45 | role-to-assume: ${{ secrets.JAVASCRIPT_IAM_ROLE }} 46 | aws-region: us-east-1 47 | 48 | - name: Configure and run integration for nodejs HowTo 49 | working-directory: ./javascript/node-postgres 50 | env: 51 | CLUSTER_ENDPOINT: ${{ secrets.JAVASCRIPT_NODEJS_CLUSTER_ENDPOINT }} 52 | REGION: ${{ secrets.JAVASCRIPT_NODEJS_CLUSTER_REGION }} 53 | CLUSTER_USER: 'admin' 54 | run: | 55 | npm ci 56 | npm test 57 | -------------------------------------------------------------------------------- /.github/workflows/java-pgjdbc-integ-tests.yml: -------------------------------------------------------------------------------- 1 | name: Java pgJDBC integration tests 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [ main ] 8 | paths: 9 | - 'java/pgjdbc/**' 10 | - '.github/workflows/java-pgjdbc-integ-tests.yml' 11 | pull_request: 12 | branches: [ main ] 13 | paths: 14 | - 'java/pgjdbc/**' 15 | - '.github/workflows/java-pgjdbc-integ-tests.yml' 16 | # Give us a button to allow running the workflow on demand for testing. 17 | workflow_dispatch: 18 | inputs: 19 | tags: 20 | description: 'Manual Workflow Run' 21 | required: false 22 | type: string 23 | 24 | jobs: 25 | test: 26 | runs-on: ubuntu-latest 27 | permissions: 28 | id-token: write # required by aws-actions/configure-aws-credentials 29 | concurrency: 30 | # Ensure only 1 job uses the workflow cluster at a time. 31 | group: ${{ github.workflow }} 32 | 33 | steps: 34 | - name: Checkout code 35 | uses: actions/checkout@v4 36 | 37 | - name: Set up JDK 17 38 | uses: actions/setup-java@v4 39 | with: 40 | java-version: '17' 41 | distribution: 'corretto' 42 | architecture: x64 43 | cache: maven 44 | 45 | - name: Configure AWS Credentials 46 | uses: aws-actions/configure-aws-credentials@v4 47 | with: 48 | role-to-assume: ${{ secrets.JAVA_IAM_ROLE }} 49 | aws-region: us-east-1 50 | 51 | - name: Configure and run integration for pgjdbc - admin 52 | working-directory: ./java/pgjdbc 53 | env: 54 | CLUSTER_ENDPOINT: ${{ secrets.JAVA_PGJDBC_CLUSTER_ENDPOINT }} 55 | CLUSTER_USER: admin 56 | REGION: ${{ secrets.JAVA_PGJDBC_CLUSTER_REGION }} 57 | run: | 58 | mvn validate 59 | mvn initialize 60 | mvn compile 61 | mvn test 62 | -------------------------------------------------------------------------------- /.github/workflows/javascript-postgresjs-integ-tests.yml: -------------------------------------------------------------------------------- 1 | name: JavaScript Postgres.js integration tests 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [ main ] 8 | paths: 9 | - 'javascript/postgres-js/**' 10 | - '.github/workflows/javascript-postgresjs-integ-tests.yml' 11 | pull_request: 12 | branches: [ main ] 13 | paths: 14 | - 'javascript/postgres-js/**' 15 | - '.github/workflows/javascript-postgresjs-integ-tests.yml' 16 | # Give us a button to allow running the workflow on demand for testing. 17 | workflow_dispatch: 18 | inputs: 19 | tags: 20 | description: 'Manual Workflow Run' 21 | required: false 22 | type: string 23 | 24 | jobs: 25 | postgresjs-integ-test: 26 | runs-on: ubuntu-latest 27 | permissions: 28 | id-token: write # required by aws-actions/configure-aws-credentials 29 | concurrency: 30 | # Ensure only 1 job uses the workflow cluster at a time. 31 | group: ${{ github.workflow }} 32 | 33 | steps: 34 | - name: Checkout code 35 | uses: actions/checkout@v4 36 | 37 | - name: Set up Node 38 | uses: actions/setup-node@v4 39 | with: 40 | node-version: '22.x' 41 | 42 | - name: Configure AWS Credentials 43 | uses: aws-actions/configure-aws-credentials@v4 44 | with: 45 | role-to-assume: ${{ secrets.JAVASCRIPT_IAM_ROLE }} 46 | aws-region: us-east-1 47 | 48 | - name: Configure and run integration for nodejs HowTo 49 | working-directory: ./javascript/postgres-js 50 | env: 51 | CLUSTER_ENDPOINT: ${{ secrets.JAVASCRIPT_POSTGRESJS_CLUSTER_ENDPOINT }} 52 | REGION: ${{ secrets.JAVASCRIPT_POSTGRESJS_CLUSTER_REGION }} 53 | CLUSTER_USER: 'admin' 54 | run: | 55 | npm ci 56 | npm test 57 | -------------------------------------------------------------------------------- /rust/cluster_management/src/bin/get_cluster.rs: -------------------------------------------------------------------------------- 1 | use aws_config::load_defaults; 2 | use aws_sdk_dsql::operation::get_cluster::GetClusterOutput; 3 | use aws_sdk_dsql::{ 4 | Client, Config, 5 | config::{BehaviorVersion, Region}, 6 | }; 7 | use std::env; 8 | 9 | /// Create a client. We will use this later for performing operations on the cluster. 10 | async fn dsql_client(region: &str) -> anyhow::Result { 11 | // Load default SDK configuration 12 | let sdk_defaults = load_defaults(BehaviorVersion::latest()).await; 13 | 14 | // You can set your own credentials by following this guide 15 | // https://docs.aws.amazon.com/sdk-for-rust/latest/dg/credproviders.html 16 | let credentials = sdk_defaults 17 | .credentials_provider() 18 | .ok_or_else(|| anyhow::anyhow!("Failed to obtain credentials provider"))?; 19 | 20 | let config = Config::builder() 21 | .behavior_version(BehaviorVersion::latest()) 22 | .credentials_provider(credentials) 23 | .region(Region::new(region.to_owned())) 24 | .build(); 25 | 26 | Ok(Client::from_conf(config)) 27 | } 28 | 29 | /// Get the details of the provided DSQL cluster. 30 | pub async fn get_cluster(region: &str, identifier: &str) -> anyhow::Result { 31 | let client = dsql_client(region).await?; 32 | let result = client.get_cluster().identifier(identifier).send().await?; 33 | 34 | Ok(result) 35 | } 36 | 37 | #[tokio::main(flavor = "current_thread")] 38 | pub async fn main() -> anyhow::Result<()> { 39 | let region = env::var("CLUSTER_REGION").expect("env variable `CLUSTER_REGION` should be set"); 40 | let cluster_id = env::var("CLUSTER_ID").expect("env variable `CLUSTER_ID` should be set"); 41 | 42 | let cluster = get_cluster(®ion, &cluster_id).await?; 43 | println!("{:#?}", cluster); 44 | 45 | Ok(()) 46 | } 47 | -------------------------------------------------------------------------------- /go/cluster_management/README.md: -------------------------------------------------------------------------------- 1 | # Aurora DSQL Go SDK code examples 2 | 3 | ## Overview 4 | 5 | The code examples in this topic show you how to use the AWS Go SDK with DSQL to create, read, update, and delete clusters. 6 | 7 | ## Run the examples 8 | 9 | ### ⚠️ Important 10 | 11 | * Running this code might result in charges to your AWS account. 12 | * We recommend that you grant your code least privilege. At most, grant only the 13 | minimum permissions required to perform the task. For more information, see 14 | [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege). 15 | * This code is not tested in every AWS Region. For more information, see 16 | [AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services). 17 | 18 | ### Prerequisites 19 | 20 | * Go version >= 1.21 21 | * Valid AWS credentials can be discovered by the [default provider chain](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials-chain.html). 22 | 23 | ### Setup test running environment 24 | 25 | Ensure you are authenticated with AWS credentials. No other setup is needed besides having Go installed. 26 | 27 | ### Run the example tests 28 | 29 | In a terminal run the following commands: 30 | 31 | 32 | 33 | ### Execute tests to create and delete clusters 34 | ```sh 35 | make test 36 | ``` 37 | 38 | OR 39 | 40 | ```shell 41 | go env -w GOPROXY=direct 42 | go test -v -count=1 ./cmd/create_multi_region 43 | go test -v -count=1 ./cmd/create_single_region 44 | go test -v -count=1 ./cmd/get_cluster 45 | go test -v -count=1 ./cmd/update_cluster 46 | go test -v -count=1 ./cmd/delete_multi_region 47 | go test -v -count=1 ./cmd/delete_single_region 48 | ``` 49 | 50 | --- 51 | 52 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 53 | 54 | SPDX-License-Identifier: MIT-0 55 | -------------------------------------------------------------------------------- /java/liquibase/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | com.amazon.dsql 9 | liquibase-dsql 10 | 1.0.0 11 | 12 | 13 | 11 14 | 11 15 | 4.24.0 16 | 17 | 18 | 19 | 20 | org.liquibase 21 | liquibase-core 22 | ${liquibase.version} 23 | 24 | 25 | software.amazon.dsql 26 | aurora-dsql-jdbc-connector 27 | 1.3.0 28 | 29 | 30 | 31 | 32 | 33 | 34 | org.liquibase 35 | liquibase-maven-plugin 36 | ${liquibase.version} 37 | 38 | jdbc:aws-dsql:postgresql://${env.CLUSTER_ENDPOINT}:5432/postgres 39 | software.amazon.dsql.jdbc.DSQLConnector 40 | admin 41 | changelog.sql 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /typescript/prisma/prisma/migrations/0_init/migration.sql: -------------------------------------------------------------------------------- 1 | -- Migration initially generated using the following command: 2 | -- 3 | -- npx prisma migrate diff 4 | -- --from-empty 5 | -- --to-schema-datamodel prisma/veterinary-schema.prisma 6 | -- --script 7 | -- > prisma/migrations/0_init/migration.sql 8 | -- 9 | -- Manual changes were made based on the considerations mentioned in the project README.md file. 10 | 11 | -- CreateTable 12 | BEGIN; 13 | CREATE TABLE "owner" ( 14 | "id" UUID NOT NULL DEFAULT gen_random_uuid(), 15 | "name" VARCHAR(30) NOT NULL, 16 | "city" VARCHAR(80) NOT NULL, 17 | "telephone" VARCHAR(20), 18 | 19 | CONSTRAINT "owner_pkey" PRIMARY KEY ("id") 20 | ); 21 | COMMIT; 22 | 23 | -- CreateTable 24 | BEGIN; 25 | CREATE TABLE "pet" ( 26 | "id" UUID NOT NULL DEFAULT gen_random_uuid(), 27 | "name" VARCHAR(30) NOT NULL, 28 | "birthDate" DATE NOT NULL, 29 | "ownerId" UUID, 30 | 31 | CONSTRAINT "pet_pkey" PRIMARY KEY ("id") 32 | ); 33 | COMMIT; 34 | 35 | -- CreateTable 36 | BEGIN; 37 | CREATE TABLE "specialty" ( 38 | "name" VARCHAR(80) NOT NULL, 39 | 40 | CONSTRAINT "specialty_pkey" PRIMARY KEY ("name") 41 | ); 42 | COMMIT; 43 | 44 | -- CreateTable 45 | BEGIN; 46 | CREATE TABLE "vet" ( 47 | "id" UUID NOT NULL DEFAULT gen_random_uuid(), 48 | "name" VARCHAR(30) NOT NULL, 49 | 50 | CONSTRAINT "vet_pkey" PRIMARY KEY ("id") 51 | ); 52 | COMMIT; 53 | 54 | -- CreateTable 55 | BEGIN; 56 | CREATE TABLE "_SpecialtyToVet" ( 57 | "A" VARCHAR(80) NOT NULL, 58 | "B" UUID NOT NULL, 59 | 60 | CONSTRAINT "_SpecialtyToVet_AB_pkey" PRIMARY KEY ("A","B") 61 | ); 62 | COMMIT; 63 | 64 | -- CreateIndex 65 | BEGIN; 66 | CREATE INDEX ASYNC "pet_ownerId_idx" ON "pet"("ownerId"); 67 | COMMIT; 68 | 69 | -- CreateIndex 70 | BEGIN; 71 | CREATE INDEX ASYNC "_SpecialtyToVet_B_index" ON "_SpecialtyToVet"("B"); 72 | COMMIT; 73 | 74 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/public/406-unsupported-browser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Your browser is not supported (406) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

Your browser is not supported.

62 |

Please upgrade your browser to continue.

63 |
64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /dotnet/cluster_management/examples/GetCluster/GetCluster.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Amazon; 3 | using Amazon.DSQL; 4 | using Amazon.DSQL.Model; 5 | using Amazon.Runtime.Credentials; 6 | 7 | namespace DSQLExamples.GetCluster; 8 | 9 | public class GetCluster 10 | { 11 | /// 12 | /// Create a client. We will use this later for performing operations on the cluster. 13 | /// 14 | private static async Task CreateDSQLClient(RegionEndpoint region) 15 | { 16 | var awsCredentials = await DefaultAWSCredentialsIdentityResolver.GetCredentialsAsync(); 17 | var clientConfig = new AmazonDSQLConfig 18 | { 19 | RegionEndpoint = region 20 | }; 21 | return new AmazonDSQLClient(awsCredentials, clientConfig); 22 | } 23 | 24 | /// 25 | /// Get information about a DSQL cluster. 26 | /// 27 | public static async Task Get(RegionEndpoint region, string identifier) 28 | { 29 | using var client = await CreateDSQLClient(region); 30 | 31 | var getClusterRequest = new GetClusterRequest 32 | { 33 | Identifier = identifier 34 | }; 35 | 36 | return await client.GetClusterAsync(getClusterRequest); 37 | } 38 | 39 | public static async Task Main() 40 | { 41 | var regionName = Environment.GetEnvironmentVariable("CLUSTER_REGION"); 42 | Debug.Assert(!string.IsNullOrEmpty(regionName), "Environment variable `CLUSTER_REGION` must be set"); 43 | var region = RegionEndpoint.GetBySystemName(regionName); 44 | 45 | var clusterId = Environment.GetEnvironmentVariable("CLUSTER_ID"); 46 | Debug.Assert(!string.IsNullOrEmpty(clusterId), "Environment variable `CLUSTER_ID` must be set"); 47 | 48 | var response = await Get(region, clusterId); 49 | Console.WriteLine($"Cluster ARN: {response.Arn}"); 50 | } 51 | } -------------------------------------------------------------------------------- /java/spring_boot/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | org.springframework.boot 9 | spring-boot-starter-parent 10 | 3.5.6 11 | 12 | 13 | 14 | org.example 15 | aurora-dsql-spring-boot 16 | 1.0.0 17 | jar 18 | 19 | 20 | 17 21 | 17 22 | UTF-8 23 | 1.2.0 24 | 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-data-jdbc 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | software.amazon.dsql 37 | aurora-dsql-jdbc-connector 38 | ${connector.version} 39 | 40 | 41 | 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-maven-plugin 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /.github/workflows/java-pgjdbc-hikaricp-integ-tests.yml: -------------------------------------------------------------------------------- 1 | name: Java pgJDBC integration tests 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [main] 8 | paths: 9 | - "java/pgjdbc_hikaricp/**" 10 | - ".github/workflows/java-pgjdbc-hikari-integcp-tests.yml" 11 | pull_request: 12 | branches: [main] 13 | paths: 14 | - "java/pgjdbc_hikaricp/**" 15 | - ".github/workflows/java-pgjdbc-hikari-integcp-tests.yml" 16 | # Give us a button to allow running the workflow on demand for testing. 17 | workflow_dispatch: 18 | inputs: 19 | tags: 20 | description: "Manual Workflow Run" 21 | required: false 22 | type: string 23 | 24 | jobs: 25 | test: 26 | runs-on: ubuntu-latest 27 | permissions: 28 | id-token: write # required by aws-actions/configure-aws-credentials 29 | concurrency: 30 | # Ensure only 1 job uses the workflow cluster at a time. 31 | group: ${{ github.workflow }} 32 | 33 | steps: 34 | - name: Checkout code 35 | uses: actions/checkout@v4 36 | 37 | - name: Set up JDK 17 38 | uses: actions/setup-java@v4 39 | with: 40 | java-version: "17" 41 | distribution: "corretto" 42 | architecture: x64 43 | cache: maven 44 | 45 | - name: Configure AWS Credentials 46 | uses: aws-actions/configure-aws-credentials@v4 47 | with: 48 | role-to-assume: ${{ secrets.JAVA_IAM_ROLE }} 49 | aws-region: us-east-1 50 | 51 | - name: Configure and run integration for pgjdbc - admin 52 | working-directory: ./java/pgjdbc_hikaricp 53 | env: 54 | CLUSTER_ENDPOINT: ${{ secrets.JAVA_PGJDBC_HIKARI_CLUSTER_ENDPOINT }} 55 | CLUSTER_USER: admin 56 | REGION: ${{ secrets.JAVA_PGJDBC_HIKARI_CLUSTER_REGION }} 57 | run: | 58 | mvn validate 59 | mvn initialize 60 | mvn compile 61 | mvn test 62 | -------------------------------------------------------------------------------- /.github/workflows/typescript-type-orm-integ-tests.yml: -------------------------------------------------------------------------------- 1 | name: TypeScript TypeORM integration tests 2 | 3 | permissions: {} 4 | 5 | on: 6 | push: 7 | branches: [main] 8 | paths: 9 | - "typescript/type-orm/**" 10 | - ".github/workflows/typescript-type-orm-integ-tests.yml" 11 | pull_request: 12 | branches: [main] 13 | paths: 14 | - "typescript/type-orm/**" 15 | - ".github/workflows/typescript-type-orm-integ-tests.yml" 16 | # Give us a button to allow running the workflow on demand for testing. 17 | workflow_dispatch: 18 | inputs: 19 | tags: 20 | description: "Manual Workflow Run" 21 | required: false 22 | type: string 23 | 24 | jobs: 25 | type-orm-integ-test: 26 | runs-on: ubuntu-latest 27 | permissions: 28 | id-token: write # required by aws-actions/configure-aws-credentials 29 | concurrency: 30 | # Ensure only 1 job uses the workflow cluster at a time. 31 | group: ${{ github.workflow }} 32 | 33 | steps: 34 | - name: Checkout code 35 | uses: actions/checkout@v4 36 | 37 | - name: Set up Node 38 | uses: actions/setup-node@v4 39 | with: 40 | node-version: "18.x" 41 | 42 | - name: Configure AWS Credentials 43 | uses: aws-actions/configure-aws-credentials@v4 44 | with: 45 | role-to-assume: ${{ secrets.TYPESCRIPT_IAM_ROLE }} 46 | aws-region: us-east-1 47 | 48 | - name: Configure and run integration for typeORM HowTo 49 | working-directory: ./typescript/type-orm 50 | env: 51 | CLUSTER_USER: "admin" 52 | CLUSTER_ENDPOINT: ${{ secrets.TYPESCRIPT_TYPE_ORM_CLUSTER_ENDPOINT }} 53 | REGION: ${{ secrets.TYPESCRIPT_TYPE_ORM_CLUSTER_REGION }} 54 | run: | 55 | npm ci 56 | npm run build 57 | npm run migrations-drop-table 58 | npm run migrations-create-table 59 | npm run migrations-run 60 | npm test 61 | -------------------------------------------------------------------------------- /dotnet/cluster_management/examples/DeleteSingleRegionCluster/DeleteSingleRegionCluster.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Amazon; 3 | using Amazon.DSQL; 4 | using Amazon.DSQL.Model; 5 | using Amazon.Runtime.Credentials; 6 | 7 | namespace DSQLExamples.DeleteSingleRegionCluster; 8 | 9 | public class DeleteSingleRegionCluster 10 | { 11 | /// 12 | /// Create a client. We will use this later for performing operations on the cluster. 13 | /// 14 | private static async Task CreateDSQLClient(RegionEndpoint region) 15 | { 16 | var awsCredentials = await DefaultAWSCredentialsIdentityResolver.GetCredentialsAsync(); 17 | var clientConfig = new AmazonDSQLConfig 18 | { 19 | RegionEndpoint = region 20 | }; 21 | return new AmazonDSQLClient(awsCredentials, clientConfig); 22 | } 23 | 24 | /// 25 | /// Delete a DSQL cluster. 26 | /// 27 | public static async Task Delete(RegionEndpoint region, string identifier) 28 | { 29 | using var client = await CreateDSQLClient(region); 30 | 31 | var deleteRequest = new DeleteClusterRequest 32 | { 33 | Identifier = identifier 34 | }; 35 | 36 | var deleteResponse = await client.DeleteClusterAsync(deleteRequest); 37 | Console.WriteLine($"Initiated deletion of {deleteResponse.Arn}"); 38 | } 39 | 40 | public static async Task Main() 41 | { 42 | var regionName = Environment.GetEnvironmentVariable("CLUSTER_REGION"); 43 | Debug.Assert(!string.IsNullOrEmpty(regionName), "Environment variable `CLUSTER_REGION` must be set"); 44 | var region = RegionEndpoint.GetBySystemName(regionName); 45 | 46 | var clusterId = Environment.GetEnvironmentVariable("CLUSTER_ID"); 47 | Debug.Assert(!string.IsNullOrEmpty(clusterId), "Environment variable `CLUSTER_ID` must be set"); 48 | 49 | await Delete(region, clusterId); 50 | } 51 | } -------------------------------------------------------------------------------- /rust/cluster_management/src/bin/update_cluster.rs: -------------------------------------------------------------------------------- 1 | use aws_config::load_defaults; 2 | use aws_sdk_dsql::operation::update_cluster::UpdateClusterOutput; 3 | use aws_sdk_dsql::{ 4 | Client, Config, 5 | config::{BehaviorVersion, Region}, 6 | }; 7 | use std::env; 8 | 9 | /// Create a client. We will use this later for performing operations on the cluster. 10 | async fn dsql_client(region: &str) -> anyhow::Result { 11 | // Load default SDK configuration 12 | let sdk_defaults = load_defaults(BehaviorVersion::latest()).await; 13 | 14 | // You can set your own credentials by following this guide 15 | // https://docs.aws.amazon.com/sdk-for-rust/latest/dg/credproviders.html 16 | let credentials = sdk_defaults 17 | .credentials_provider() 18 | .ok_or_else(|| anyhow::anyhow!("Failed to obtain credentials provider"))?; 19 | 20 | let config = Config::builder() 21 | .behavior_version(BehaviorVersion::latest()) 22 | .credentials_provider(credentials) 23 | .region(Region::new(region.to_owned())) 24 | .build(); 25 | 26 | Ok(Client::from_conf(config)) 27 | } 28 | 29 | /// Update a DSQL cluster and set delete protection to false. 30 | pub async fn update_cluster(region: &str, identifier: &str) -> anyhow::Result { 31 | let client = dsql_client(region).await?; 32 | let result = client 33 | .update_cluster() 34 | .identifier(identifier) 35 | .deletion_protection_enabled(false) 36 | .send() 37 | .await?; 38 | 39 | Ok(result) 40 | } 41 | 42 | #[tokio::main(flavor = "current_thread")] 43 | pub async fn main() -> anyhow::Result<()> { 44 | let region = env::var("CLUSTER_REGION").expect("env variable `CLUSTER_REGION` should be set"); 45 | let cluster_id = env::var("CLUSTER_ID").expect("env variable `CLUSTER_ID` should be set"); 46 | 47 | let cluster = update_cluster(®ion, &cluster_id).await?; 48 | println!("{:#?}", cluster); 49 | 50 | Ok(()) 51 | } 52 | -------------------------------------------------------------------------------- /java/cluster_management/src/main/java/org/example/DeleteCluster.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import java.time.Duration; 4 | import java.util.Optional; 5 | 6 | import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; 7 | import software.amazon.awssdk.regions.Region; 8 | import software.amazon.awssdk.retries.api.BackoffStrategy; 9 | import software.amazon.awssdk.services.dsql.DsqlClient; 10 | import software.amazon.awssdk.services.dsql.model.DeleteClusterResponse; 11 | 12 | public class DeleteCluster { 13 | 14 | public static void main(String[] args) { 15 | Region region = Region.of(System.getenv().getOrDefault("CLUSTER_REGION", "us-east-1")); 16 | String clusterId = Optional.ofNullable(System.getenv("CLUSTER_ID")) 17 | .orElseThrow(() -> new IllegalStateException("Expected CLUSTER_ID in environment")); 18 | 19 | try ( 20 | DsqlClient client = DsqlClient.builder() 21 | .region(region) 22 | .credentialsProvider(DefaultCredentialsProvider.create()) 23 | .build() 24 | ) { 25 | example(client, clusterId); 26 | } 27 | } 28 | 29 | public static void example(DsqlClient client, String clusterId) { 30 | DeleteClusterResponse cluster = client.deleteCluster(r -> r.identifier(clusterId)); 31 | System.out.println("Initiated delete of " + cluster.arn()); 32 | 33 | // The DSQL SDK offers a built-in waiter to poll for deletion. 34 | System.out.println("Waiting for cluster to finish deletion"); 35 | client.waiter().waitUntilClusterNotExists( 36 | getCluster -> getCluster.identifier(clusterId), 37 | config -> config.backoffStrategyV2( 38 | BackoffStrategy.fixedDelayWithoutJitter(Duration.ofSeconds(10)) 39 | ).waitTimeout(Duration.ofMinutes(5)) 40 | ); 41 | System.out.println("Deleted " + cluster.arn()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /go/cluster_management/internal/util/find_cluster.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/aws/aws-sdk-go-v2/config" 7 | "github.com/aws/aws-sdk-go-v2/service/dsql" 8 | "log" 9 | "os" 10 | ) 11 | 12 | func GetEnvWithDefault(key, defaultValue string) string { 13 | value := os.Getenv(key) 14 | if value == "" { 15 | return defaultValue 16 | } 17 | return value 18 | } 19 | 20 | func GetUniqueRunTagName(tagPrefix string) string { 21 | uniqueId := GetEnvWithDefault("GITHUB_RUN_ID", "1") 22 | return tagPrefix + " - " + uniqueId 23 | } 24 | 25 | // FindClusterWithTagAndRepository finds an Aurora cluster by a specific tag name and value. 26 | func FindClusterWithTagAndRepository(ctx context.Context, region, tagName, tagValue string) (*dsql.GetClusterOutput, error) { 27 | if tagName == "" || tagValue == "" { 28 | return nil, fmt.Errorf("tagName and tagValue cannot be empty") 29 | } 30 | 31 | cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(region)) 32 | if err != nil { 33 | log.Fatalf("Failed to load AWS configuration: %v", err) 34 | } 35 | 36 | // Initialize the DSQL client 37 | client := dsql.NewFromConfig(cfg) 38 | 39 | clustersOutput, err := client.ListClusters(ctx, &dsql.ListClustersInput{}) 40 | 41 | if err != nil { 42 | log.Fatalf("Failed to list clusters: %v", err) 43 | } 44 | 45 | for _, val := range clustersOutput.Clusters { 46 | clusterOutput, err := client.GetCluster(ctx, &dsql.GetClusterInput{Identifier: val.Identifier}) 47 | if err != nil { 48 | log.Fatalf("Failed to get cluster: %v", err) 49 | } 50 | 51 | if clusterOutput.Tags[tagName] == tagValue && clusterOutput.Tags["Repo"] == os.Getenv("GITHUB_REPOSITORY") && 52 | (clusterOutput.Status == "ACTIVE" || clusterOutput.Status == "PENDING_SETUP") { 53 | fmt.Println("found cluster:" + *val.Identifier + " with tag:" + tagName + "=" + tagValue) 54 | return clusterOutput, nil 55 | } 56 | } 57 | 58 | return nil, fmt.Errorf("no cluster found with tag %s=%s", tagName, tagValue) 59 | } 60 | -------------------------------------------------------------------------------- /ruby/rails/petclinic/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /java/spring_boot/src/main/java/org/example/Application.java: -------------------------------------------------------------------------------- 1 | package org.example; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.boot.web.client.RestTemplateBuilder; 8 | import org.springframework.context.ConfigurableApplicationContext; 9 | import org.springframework.web.client.RestTemplate; 10 | 11 | @SpringBootApplication 12 | public class Application implements CommandLineRunner { 13 | 14 | private final DatabaseService databaseService; 15 | private final ConfigurableApplicationContext context; 16 | private final RestTemplate restTemplate; 17 | 18 | @Value("${app.exit-after-test:false}") 19 | private boolean exitAfterTest; 20 | 21 | @Value("${server.port:8080}") 22 | private int serverPort; 23 | 24 | public Application( 25 | final DatabaseService databaseService, 26 | final ConfigurableApplicationContext context, 27 | final RestTemplateBuilder restTemplateBuilder) { 28 | this.databaseService = databaseService; 29 | this.context = context; 30 | this.restTemplate = restTemplateBuilder.build(); 31 | } 32 | 33 | public static void main(final String[] args) { 34 | SpringApplication.run(Application.class, args); 35 | } 36 | 37 | @Override 38 | public void run(final String... args) throws Exception { 39 | databaseService.testConnection(); 40 | System.out.println("Database operations test completed successfully"); 41 | 42 | final String url = "http://localhost:" + serverPort + "/select1"; 43 | final Integer result = restTemplate.getForObject(url, Integer.class); 44 | assert result != null && result.equals(1); 45 | System.out.println("REST API endpoint test completed successfully"); 46 | 47 | if (exitAfterTest) { 48 | context.close(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /dotnet/cluster_management/examples/CreateSingleRegionCluster/CreateSingleRegionCluster.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Amazon; 3 | using Amazon.DSQL; 4 | using Amazon.DSQL.Model; 5 | using Amazon.Runtime.Credentials; 6 | 7 | namespace DSQLExamples.CreateSingleRegionCluster; 8 | 9 | public class CreateSingleRegionCluster 10 | { 11 | /// 12 | /// Create a client. We will use this later for performing operations on the cluster. 13 | /// 14 | private static async Task CreateDSQLClient(RegionEndpoint region) 15 | { 16 | var awsCredentials = await DefaultAWSCredentialsIdentityResolver.GetCredentialsAsync(); 17 | var clientConfig = new AmazonDSQLConfig 18 | { 19 | RegionEndpoint = region 20 | }; 21 | return new AmazonDSQLClient(awsCredentials, clientConfig); 22 | } 23 | 24 | /// 25 | /// Create an example DSQL cluster. 26 | /// 27 | public static async Task Create(RegionEndpoint region) 28 | { 29 | using var client = await CreateDSQLClient(region); 30 | 31 | var createClusterRequest = new CreateClusterRequest 32 | { 33 | DeletionProtectionEnabled = true, 34 | Tags = new Dictionary 35 | { 36 | { "Name", "csharp single region cluster" }, 37 | { "Repo", "aws-samples/aurora-dsql-samples" } 38 | } 39 | }; 40 | 41 | CreateClusterResponse response = await client.CreateClusterAsync(createClusterRequest); 42 | Console.WriteLine($"Initiated creation of {response.Arn}"); 43 | 44 | return response; 45 | } 46 | 47 | public static async Task Main() 48 | { 49 | var regionName = Environment.GetEnvironmentVariable("CLUSTER_REGION"); 50 | Debug.Assert(!string.IsNullOrEmpty(regionName), "Environment variable `CLUSTER_REGION` must be set"); 51 | var region = RegionEndpoint.GetBySystemName(regionName); 52 | 53 | await Create(region); 54 | } 55 | } -------------------------------------------------------------------------------- /typescript/type-orm/src/migrations/1731957649222-BaseMigration.ts: -------------------------------------------------------------------------------- 1 | import { MigrationInterface, QueryRunner } from "typeorm"; 2 | 3 | export class BaseMigration1731957649222 implements MigrationInterface { 4 | 5 | public async up(queryRunner: QueryRunner): Promise { 6 | await queryRunner.query(`CREATE TABLE IF NOT EXISTS owner ( 7 | id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 8 | name VARCHAR(30) NOT NULL, 9 | city VARCHAR(80) NOT NULL, 10 | telephone VARCHAR(20))`); 11 | 12 | await queryRunner.query(`CREATE TABLE IF NOT EXISTS pet ( 13 | id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 14 | name VARCHAR(30) NOT NULL, 15 | birth_date TIMESTAMP NOT NULL, 16 | owner_id UUID NULL)`); 17 | 18 | await queryRunner.query(`CREATE TABLE IF NOT EXISTS vet_specialty ( 19 | id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 20 | vet_id UUID NULL, 21 | specialty_name VARCHAR(80) NULL)`); 22 | 23 | await queryRunner.query(`CREATE TABLE IF NOT EXISTS specialty ( 24 | name VARCHAR(80) PRIMARY KEY)`); 25 | 26 | await queryRunner.query(`CREATE TABLE IF NOT EXISTS vet ( 27 | id UUID PRIMARY KEY DEFAULT gen_random_uuid(), 28 | name VARCHAR(30) NOT NULL)`); 29 | } 30 | 31 | public async down(queryRunner: QueryRunner): Promise { 32 | await queryRunner.query(`DROP TABLE IF EXISTS owner`); 33 | 34 | await queryRunner.query(`DROP TABLE IF EXISTS pet`); 35 | 36 | await queryRunner.query(`DROP TABLE IF EXISTS vet_specialty`); 37 | 38 | await queryRunner.query(`DROP TABLE IF EXISTS specialty`); 39 | 40 | await queryRunner.query(`DROP TABLE IF EXISTS vet`); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /dotnet/cluster_management/examples/UpdateCluster/UpdateCluster.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Amazon; 3 | using Amazon.DSQL; 4 | using Amazon.DSQL.Model; 5 | using Amazon.Runtime.Credentials; 6 | 7 | namespace DSQLExamples.UpdateCluster; 8 | 9 | public class UpdateCluster 10 | { 11 | /// 12 | /// Create a client. We will use this later for performing operations on the cluster. 13 | /// 14 | private static async Task CreateDSQLClient(RegionEndpoint region) 15 | { 16 | var awsCredentials = await DefaultAWSCredentialsIdentityResolver.GetCredentialsAsync(); 17 | var clientConfig = new AmazonDSQLConfig 18 | { 19 | RegionEndpoint = region 20 | }; 21 | return new AmazonDSQLClient(awsCredentials, clientConfig); 22 | } 23 | 24 | /// 25 | /// Update a DSQL cluster and set delete protection to false. 26 | /// 27 | public static async Task Update(RegionEndpoint region, string identifier) 28 | { 29 | using var client = await CreateDSQLClient(region); 30 | 31 | var updateClusterRequest = new UpdateClusterRequest 32 | { 33 | Identifier = identifier, 34 | DeletionProtectionEnabled = false 35 | }; 36 | 37 | UpdateClusterResponse response = await client.UpdateClusterAsync(updateClusterRequest); 38 | Console.WriteLine($"Updated {response.Arn}"); 39 | 40 | return response; 41 | } 42 | 43 | public static async Task Main() 44 | { 45 | var regionName = Environment.GetEnvironmentVariable("CLUSTER_REGION"); 46 | Debug.Assert(!string.IsNullOrEmpty(regionName), "Environment variable `CLUSTER_REGION` must be set"); 47 | var region = RegionEndpoint.GetBySystemName(regionName); 48 | 49 | var clusterId = Environment.GetEnvironmentVariable("CLUSTER_ID"); 50 | Debug.Assert(!string.IsNullOrEmpty(clusterId), "Environment variable `CLUSTER_ID` must be set"); 51 | 52 | await Update(region, clusterId); 53 | } 54 | } -------------------------------------------------------------------------------- /typescript/prisma/src/veterinary-service.ts: -------------------------------------------------------------------------------- 1 | import { DsqlPrismaClient } from "./dsql-client"; 2 | import { owner, specialty } from "@generated/prisma-vet/client"; 3 | 4 | export class VeterinaryService { 5 | constructor(private readonly prisma: DsqlPrismaClient) {} 6 | 7 | async createOwner(name: string, city: string, telephone?: string) { 8 | return this.prisma.owner.create({ 9 | data: { name, city, telephone: telephone ?? null }, 10 | }); 11 | } 12 | 13 | async createPet(name: string, birthDate: Date, owner: owner) { 14 | return this.prisma.pet.create({ 15 | data: { 16 | name, 17 | birthDate, 18 | owner: { 19 | connect: owner, 20 | }, 21 | }, 22 | }); 23 | } 24 | 25 | async createSpecialty(name: string) { 26 | return this.prisma.specialty.create({ 27 | data: { name }, 28 | }); 29 | } 30 | 31 | async createVet(name: string, specialties: specialty[]) { 32 | return this.prisma.vet.create({ 33 | data: { 34 | name, 35 | specialties: { 36 | connect: specialties, 37 | }, 38 | }, 39 | }); 40 | } 41 | 42 | async getPetWithOwner(petName: string) { 43 | return this.prisma.pet.findFirstOrThrow({ 44 | where: { name: petName }, 45 | include: { owner: true }, 46 | }); 47 | } 48 | 49 | async getOwnerWithPets(ownerName: string) { 50 | return this.prisma.owner.findFirstOrThrow({ 51 | where: { name: ownerName }, 52 | include: { pets: true }, 53 | }); 54 | } 55 | 56 | async getVetWithSpecialties(vetName: string) { 57 | return this.prisma.vet.findFirstOrThrow({ 58 | where: { name: vetName }, 59 | include: { 60 | specialties: { 61 | orderBy: { name: "asc" }, 62 | }, 63 | }, 64 | }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /typescript/type-orm/src/create-migrations-table.ts: -------------------------------------------------------------------------------- 1 | import { DsqlSigner } from "@aws-sdk/dsql-signer"; 2 | import { Client } from "pg"; 3 | import { getEnvironmentVariables } from "./utils"; 4 | import { escapeIdentifier } from "pg/lib/utils"; 5 | import fs from "fs"; 6 | import path from "path"; 7 | 8 | const createMigrationsTable = async () => { 9 | const { user, clusterEndpoint, region } = getEnvironmentVariables(); 10 | 11 | const signer = new DsqlSigner({ 12 | hostname: clusterEndpoint, 13 | region: region, 14 | }); 15 | 16 | let token: string; 17 | let client: Client | undefined; 18 | let schema = "public"; 19 | 20 | try { 21 | if (user === "admin") { 22 | token = await signer.getDbConnectAdminAuthToken(); 23 | } else { 24 | // Non admin user 25 | token = await signer.getDbConnectAuthToken(); 26 | schema = "myschema"; 27 | } 28 | 29 | client = new Client({ 30 | user: user, 31 | password: token, 32 | host: clusterEndpoint, 33 | port: 5432, 34 | database: "postgres", 35 | ssl: { 36 | rejectUnauthorized: true, 37 | }, 38 | }); 39 | 40 | await client.connect(); 41 | // The following is required to set the default schema for the migration scripts 42 | // The schema can't be changed when the migration script is generated 43 | await client.query( 44 | `ALTER USER ${escapeIdentifier(user)} 45 | set SEARCH_PATH = ${escapeIdentifier(schema)};` 46 | ); 47 | await client.query( 48 | `CREATE TABLE IF NOT EXISTS 49 | ${client.escapeIdentifier(schema)}."migrations" ( 50 | "id" UUID PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, 51 | "timestamp" bigint NOT NULL, 52 | "name" character varying NOT NULL 53 | )` 54 | ); 55 | console.log(`Created the migration table in ${schema}`); 56 | } catch (error) { 57 | console.error("Failed to create the migration table:", error); 58 | throw error; 59 | } finally { 60 | if (client) { 61 | await client.end(); 62 | } 63 | } 64 | }; 65 | 66 | createMigrationsTable(); 67 | -------------------------------------------------------------------------------- /python/cluster_management/src/delete_multi_region.py: -------------------------------------------------------------------------------- 1 | import boto3 2 | import os 3 | 4 | 5 | def delete_multi_region_clusters(region_1, cluster_id_1, region_2, cluster_id_2): 6 | try: 7 | 8 | client_1 = boto3.client("dsql", region_name=region_1) 9 | client_2 = boto3.client("dsql", region_name=region_2) 10 | 11 | client_1.delete_cluster(identifier=cluster_id_1) 12 | print(f"Deleting cluster {cluster_id_1} in {region_1}") 13 | 14 | # cluster_1 will stay in PENDING_DELETE state until cluster_2 is deleted 15 | 16 | client_2.delete_cluster(identifier=cluster_id_2) 17 | print(f"Deleting cluster {cluster_id_2} in {region_2}") 18 | 19 | # Now that both clusters have been marked for deletion they will transition 20 | # to DELETING state and finalize deletion 21 | print(f"Waiting for {cluster_id_1} to finish deletion") 22 | client_1.get_waiter("cluster_not_exists").wait( 23 | identifier=cluster_id_1, 24 | WaiterConfig={ 25 | 'Delay': 10, 26 | 'MaxAttempts': 50 27 | } 28 | ) 29 | 30 | print(f"Waiting for {cluster_id_2} to finish deletion") 31 | client_2.get_waiter("cluster_not_exists").wait( 32 | identifier=cluster_id_2, 33 | WaiterConfig={ 34 | 'Delay': 10, 35 | 'MaxAttempts': 50 36 | } 37 | ) 38 | 39 | except: 40 | print("Unable to delete cluster") 41 | raise 42 | 43 | 44 | def main(): 45 | region_1 = os.environ.get("CLUSTER_1_REGION", "us-east-1") 46 | cluster_id_1 = os.environ.get("CLUSTER_1_ID") 47 | assert cluster_id_1 is not None, "Must provide CLUSTER_1_ID" 48 | region_2 = os.environ.get("CLUSTER_2_REGION", "us-east-2") 49 | cluster_id_2 = os.environ.get("CLUSTER_2_ID") 50 | assert cluster_id_2 is not None, "Must provide CLUSTER_2_ID" 51 | 52 | delete_multi_region_clusters(region_1, cluster_id_1, region_2, cluster_id_2) 53 | print(f"Deleted {cluster_id_1} in {region_1} and {cluster_id_2} in {region_2}") 54 | 55 | 56 | if __name__ == "__main__": 57 | main() 58 | --------------------------------------------------------------------------------