āϜāĻŋāϰ⧋ āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āĻāĻŦāĻ‚ āĻĄā§‡āϟāĻžāĻŦ⧇āϏ

āϜāĻŋāϰ⧋ āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āĻāĻŦāĻ‚ āĻĄā§‡āϟāĻžāĻŦ⧇āϏ

āĻāχ āύāĻŋāĻŦāĻ¨ā§āϧāϟāĻŋ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤāĻ­āĻžāĻŦ⧇ āĻŦā§āϝāĻžāĻ–ā§āϝāĻž āĻ•āϰ⧇ āϝ⧇ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϝāĻŧ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ⧇āϰ āϏāĻŽāĻ¸ā§āϝāĻžāϗ⧁āϞāĻŋ āϏāĻŽāĻžāϧāĻžāύ āĻ•āϰāĻž āϝāĻžāϝāĻŧāĨ¤ āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ• āĻĒā§āϰāĻ¸ā§āϤ⧁āϤāĻŋ āĻ›āĻžāĻĄāĻŧāĻžāχ āĻŽā§‹āϤāĻžāϝāĻŧ⧇āύ āĻ•āϰāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧇āύ āϤāĻŦ⧇ āφāĻĒāύāĻžāϰ āωāĻ¤ā§āĻĒāĻžāĻĻāύ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϗ⧁āϞāĻŋāϰ āϕ⧀ āϘāϟāϤ⧇ āĻĒāĻžāϰ⧇ āϤāĻž āφāĻŽāϰāĻž āφāĻĒāύāĻžāϕ⧇ āĻŦāϞāĻŦ⧎ āϤāĻžāϰāĻĒāϰ⧇ āφāĻŽāϰāĻž āĻļā§‚āĻ¨ā§āϝ āĻĄāĻžāωāύāϟāĻžāχāĻŽ (āĻĒā§āϰāĻžāϝāĻŧ. āϞ⧇āύ: āφāϰāĻ“ - āĻļā§‚āĻ¨ā§āϝ āĻĄāĻžāωāύāϟāĻžāχāĻŽ) āφāĻŽāĻžāĻĻ⧇āϰ āĻ•ā§āϰāĻŋāϝāĻŧāĻžāĻ•āϞāĻžāĻĒ⧇āϰ āĻĢāϞāĻžāĻĢāϞ āĻšāĻŦ⧇ āĻĒāĻŋāĻ›āύ⧇āϰ-āĻ…āϏāĻ™ā§āĻ—āϤāĻŋāĻĒā§‚āĻ°ā§āĻŖ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύāϟāĻŋ āĻĒāĻŋāĻ›āύ⧇āϰ-āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇ āĻĒā§āϰāϝāĻŧā§‹āĻ— āĻ•āϰāĻžāĨ¤

āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āύāĻŋāĻŦāĻ¨ā§āϧ āĻĨ⧇āϕ⧇ āϕ⧋āĻĄ āωāĻĻāĻžāĻšāϰāĻŖ āĻŦ⧁āĻāϤ⧇ āϚāĻžāύ, āφāĻĒāύāĻŋ āϤāĻžāĻĻ⧇āϰ āϖ⧁āρāĻœā§‡ āĻĒ⧇āϤ⧇ āĻĒāĻžāϰ⧇āύ GitHub.

āĻ­ā§‚āĻŽāĻŋāĻ•āĻž

āĻļā§‚āĻ¨ā§āϝ āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž

āĻ•āĻŋ āĻāĻ•āϟāĻŋ āϰāĻšāĻ¸ā§āϝāĻŽāϝāĻŧ āĻļā§‚āĻ¨ā§āϝ āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž? āφāĻĒāύāĻŋ āĻāϟāĻŋ āĻŦāϞāϤ⧇ āĻĒāĻžāϰ⧇āύ āϝāĻ–āύ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋ āĻāĻŽāύāĻ­āĻžāĻŦ⧇ āĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāĻž āĻšāϝāĻŧ āϝāĻžāϤ⧇ āφāĻĒāύāĻŋ āϏāĻĢāϞāĻ­āĻžāĻŦ⧇ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋāϰ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āωāĻ¤ā§āĻĒāĻžāĻĻāύ⧇ āĻĒā§āϰāĻŦāĻ°ā§āϤāύ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ, āϝāĻ–āύ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻāϟāĻŋāϰ āĻ…āύ⧁āĻĒāϞāĻŦā§āϧāϤāĻž āϞāĻ•ā§āĻˇā§āϝ āĻ•āϰ⧇āύ āύāĻžāĨ¤ āĻāĻ•āϟāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻāĻŦāĻ‚ āϕ⧋āĻŽā§āĻĒāĻžāύāĻŋāϰ āĻĻ⧃āĻˇā§āϟāĻŋāϕ⧋āĻŖ āĻĨ⧇āϕ⧇, āĻāϟāĻŋ āϏāĻ°ā§āĻŦā§‹āĻ¤ā§āϤāĻŽ āϏāĻŽā§āĻ­āĻžāĻŦā§āϝ āĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϰ āĻĻ⧃āĻļā§āϝ āĻ•āĻžāϰāĻŖ āĻāϟāĻŋ āύāϤ⧁āύ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝāϗ⧁āϞāĻŋ āĻĒā§āϰāĻŦāĻ°ā§āϤāύ āĻ•āϰāϤ⧇ āĻāĻŦāĻ‚ āĻŦāĻžāĻ—āϗ⧁āϞāĻŋāϕ⧇ āĻŦāĻŋāĻ˜ā§āύ āĻ›āĻžāĻĄāĻŧāĻžāχ āϏāĻ‚āĻļā§‹āϧāύ āĻ•āϰāĻžāϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻ⧇āϝāĻŧ⧎

āĻāχ āĻ…āĻ°ā§āϜāύ āĻ•āĻŋāĻ­āĻžāĻŦ⧇? āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āωāĻĒāĻžāϝāĻŧ āφāϛ⧇, āĻāĻ–āĻžāύ⧇ āϤāĻžāĻĻ⧇āϰ āĻŽāĻ§ā§āϝ⧇ āĻāĻ•āϟāĻŋ:

  • āφāĻĒāύāĻžāϰ āĻĒāϰāĻŋāώ⧇āĻŦāĻžāϰ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āύāĻ‚ 1 āĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰ⧁āύ
  • āĻāĻ•āϟāĻŋ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āϏāĻžā§āϚāĻžāϞāύ
  • āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ #2 āĻāϰ āϏāĻŽāĻžāĻ¨ā§āϤāϰāĻžāϞ⧇ āφāĻĒāύāĻžāϰ āĻĒāϰāĻŋāώ⧇āĻŦāĻžāϰ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ #1 āĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰ⧁āύ
  • āϝāϤ āϤāĻžāĻĄāĻŧāĻžāϤāĻžāĻĄāĻŧāĻŋ āφāĻĒāύāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ⧇āύ āϝ⧇ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āύāĻ‚ 2 āĻāϟāĻŋāϰ āĻŽāϤ⧋ āĻ•āĻžāϜ āĻ•āϰ⧇, āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āύāĻ‚ 1 āϏāϰāĻŋāϝāĻŧ⧇ āĻĻāĻŋāύ
  • āϏāĻŽā§āĻĒāĻ¨ā§āύ!

āϏāĻšāϜ, āϤāĻžāχ āύāĻž? āĻĻ⧁āĻ°ā§āĻ­āĻžāĻ—ā§āϝāĻŦāĻļāϤ, āĻāϟāĻŋ āĻāϤ āϏāĻšāϜ āύāϝāĻŧ, āĻāĻŦāĻ‚ āφāĻŽāϰāĻž āĻĒāϰ⧇ āĻāϟāĻŋ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤāĻ­āĻžāĻŦ⧇ āĻĻ⧇āĻ–āĻŦāĨ¤ āĻāĻ–āύ āφāϰ⧇āĻ•āϟāĻŋ āĻŽā§‹āϟāĻžāĻŽā§āϟāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϰ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻĒāϰ⧀āĻ•ā§āώāĻž āĻ•āϰāĻž āϝāĻžāĻ• - āύ⧀āϞ āϏāĻŦ⧁āϜ āĻ¸ā§āĻĨāĻžāĻĒāύāĻžāĨ¤

āφāĻĒāύāĻŋ āĻ•āĻŋ āĻ•āĻ–āύāĻ“ āĻļ⧁āύ⧇āϛ⧇āύ? āύ⧀āϞ āϏāĻŦ⧁āϜ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž? āĻ•ā§āϞāĻžāωāĻĄ āĻĢāĻžāωāĻ¨ā§āĻĄā§āϰāĻŋ āĻāϟāĻŋ āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āϏāĻšāϜ āĻ•āϰ⧇ āϤ⧋āϞ⧇āĨ¤ āĻļ⧁āϧ⧁ āϤāĻžāĻ•āĻžāύ āĻāχ āύāĻŋāĻŦāĻ¨ā§āϧāϟāĻŋ, āϝ⧇āĻ–āĻžāύ⧇ āφāĻŽāϰāĻž āφāϰāĻ“ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤāĻ­āĻžāĻŦ⧇ āĻāϟāĻŋ āĻŦāĻ°ā§āĻŖāύāĻž āĻ•āϰāĻŋāĨ¤ āϏāĻ‚āĻ•ā§āώ⧇āĻĒ⧇ āϏāĻ‚āĻ•ā§āώāĻŋāĻĒā§āϤ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ, āφāϏ⧁āύ āφāĻŽāϰāĻž āφāĻĒāύāĻžāϕ⧇ āĻŽāύ⧇ āĻ•āϰāĻŋāϝāĻŧ⧇ āĻĻāĻŋāχ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āύ⧀āϞ āϏāĻŦ⧁āϜ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āĻ•āϰāϤ⧇ āĻšāϝāĻŧ:

  • āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧁āύ āϝ⧇ āφāĻĒāύāĻžāϰ āĻĒā§āϰ⧋āĻĄāĻžāĻ•āĻļāύ āϕ⧋āĻĄā§‡āϰ āĻĻ⧁āϟāĻŋ āĻ•āĻĒāĻŋ ("āύ⧀āϞ" āĻāĻŦāĻ‚ "āϏāĻŦ⧁āϜ") āĻ•āĻžāϜ āĻ•āϰāϛ⧇;
  • āύ⧀āϞ āĻĒāϰāĻŋāĻŦ⧇āĻļ⧇ āϏāĻŽāĻ¸ā§āϤ āĻŸā§āϰāĻžāĻĢāĻŋāĻ•āϕ⧇ āύāĻŋāĻ°ā§āĻĻ⧇āĻļ āĻ•āϰ⧁āύ, āϝ⧇āĻŽāύ āϝāĻžāϤ⧇ āĻĒā§āϰ⧋āĻĄāĻžāĻ•āĻļāύ āχāωāφāϰāĻāϞ āϏ⧇āĻ–āĻžāύ⧇ āύāĻŋāĻ°ā§āĻĻ⧇āĻļ āĻ•āϰ⧇;
  • āĻāĻ•āϟāĻŋ āϏāĻŦ⧁āϜ āĻĒāϰāĻŋāĻŦ⧇āĻļ⧇ āϏāĻŽāĻ¸ā§āϤ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ¸ā§āĻĨāĻžāĻĒāύ āĻāĻŦāĻ‚ āĻĒāϰ⧀āĻ•ā§āώāĻž āĻ•āϰ⧁āύ;
  • āχāωāφāϰāĻāϞāϕ⧇ āύ⧀āϞ āĻĨ⧇āϕ⧇ āϏāĻŦ⧁āϜ āĻĒāϰāĻŋāĻŦ⧇āĻļ⧇ āĻ¸ā§āϝ⧁āχāϚ āĻ•āϰ⧁āύ

āĻŦā§āϞ⧁ āĻ—ā§āϰāĻŋāύ āĻĄāĻŋāĻĒā§āϞ⧋āϝāĻŧāĻŽā§‡āĻ¨ā§āϟ āĻšāϞ āĻāĻŽāύ āĻāĻ•āϟāĻŋ āĻĒāĻ¨ā§āĻĨāĻž āϝāĻž āφāĻĒāύāĻžāϕ⧇ āĻĒā§āϰ⧋āĻĄāĻžāĻ•āĻļāύ āĻŦā§āϰ⧇āĻ•āĻŋāĻ‚ āύāĻŋāϝāĻŧ⧇ āϚāĻŋāĻ¨ā§āϤāĻž āύāĻž āĻ•āϰ⧇ āϏāĻšāĻœā§‡āχ āύāϤ⧁āύ āĻĢāĻŋāϚāĻžāϰ āĻĒā§āϰāĻŦāĻ°ā§āϤāύ āĻ•āϰāϤ⧇ āĻĻ⧇āϝāĻŧāĨ¤ āĻāϟāĻŋ āĻāχ āĻ•āĻžāϰāϪ⧇ āϝ⧇ āĻ•āĻŋāϛ⧁ āϘāϟāϞ⧇āĻ“, āφāĻĒāύāĻŋ āϏāĻšāĻœā§‡ "āĻāĻ•āϟāĻŋ āϏ⧁āχāϚ āĻĢā§āϞāĻŋāĻ• āĻ•āϰ⧇" āĻĒā§‚āĻ°ā§āĻŦāĻŦāĻ°ā§āϤ⧀ āĻĒāϰāĻŋāĻŦ⧇āĻļ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤

āωāĻĒāϰ⧇āϰ āϏāĻŽāĻ¸ā§āϤāϟāĻŋ āĻĒāĻĄāĻŧāĻžāϰ āĻĒāϰ⧇, āφāĻĒāύāĻŋ āĻĒā§āϰāĻļā§āύ āϜāĻŋāĻœā§āĻžāĻžāϏāĻž āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ: āύ⧀āϞ āϏāĻŦ⧁āϜ āĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϰ āϏāĻžāĻĨ⧇ āĻļā§‚āĻ¨ā§āϝ āĻĄāĻžāωāύāϟāĻžāχāĻŽā§‡āϰ āϕ⧀ āϏāĻŽā§āĻĒāĻ°ā§āĻ• āφāϛ⧇?

āĻ āĻŋāĻ• āφāϛ⧇, āϤāĻžāĻĻ⧇āϰ āĻŽāĻ§ā§āϝ⧇ āĻ…āύ⧇āĻ• āĻŽāĻŋāϞ āϰāϝāĻŧ⧇āϛ⧇, āϝ⧇āĻšā§‡āϤ⧁ āĻāĻ•āχ āĻĒāϰāĻŋāĻŦ⧇āĻļ⧇āϰ āĻĻ⧁āϟāĻŋ āĻ…āύ⧁āϞāĻŋāĻĒāĻŋ āĻŦāϜāĻžāϝāĻŧ āϰāĻžāĻ–āϤ⧇ āϤāĻžāĻĻ⧇āϰ āĻŦāϜāĻžāϝāĻŧ āϰāĻžāĻ–āĻžāϰ āϜāĻ¨ā§āϝ āĻĻā§āĻŦāĻŋāϗ⧁āĻŖ āĻĒā§āϰāĻšā§‡āĻˇā§āϟāĻž āĻĒā§āϰāϝāĻŧā§‹āϜāύāĨ¤ āĻ āĻ•āĻžāϰāϪ⧇ āĻ•āϝāĻŧ⧇āĻ•āϟāĻŋ āĻĻāϞ āĻĻāĻžāĻŦāĻŋ āĻ•āϰ⧇āϛ⧇ āĻŽāĻžāĻ°ā§āϟāĻŋāύ āĻĢāĻžāĻ“āϞāĻžāϰ, āĻāχ āĻĒāĻĻā§āϧāϤāĻŋāϰ āĻāĻ•āϟāĻŋ āĻŦ⧈āϚāĻŋāĻ¤ā§āϰ āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰ⧁āύ:

āφāϰ⧇āĻ•āϟāĻŋ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒ āĻšāϞ āĻāĻ•āχ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž, āĻ“āϝāĻŧ⧇āĻŦ āĻāĻŦāĻ‚ āĻĄā§‹āĻŽā§‡āύ āĻ¸ā§āϤāϰāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āύ⧀āϞ-āϏāĻŦ⧁āϜ āϏ⧁āχāϚ āϤ⧈āϰāĻŋ āĻ•āϰāĻžāĨ¤ āĻāχ āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇, āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒā§āϰāĻžāϝāĻŧāχ āĻāĻ•āϟāĻŋ āϏāĻŽāĻ¸ā§āϝāĻž āĻšāϤ⧇ āĻĒāĻžāϰ⧇, āĻŦāĻŋāĻļ⧇āώ āĻ•āϰ⧇ āϝāĻ–āύ āφāĻĒāύāĻžāϕ⧇ āϏāĻĢā§āϟāĻ“āϝāĻŧā§āϝāĻžāϰ⧇āϰ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āϏāĻŽāĻ°ā§āĻĨāύ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻāϰ āĻ¸ā§āĻ•āĻŋāĻŽāĻž āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤

āĻāĻŦāĻ‚ āĻāĻ–āĻžāύ⧇ āφāĻŽāϰāĻž āĻāχ āύāĻŋāĻŦāĻ¨ā§āϧ⧇ āĻĒā§āϰāϧāĻžāύ āϏāĻŽāĻ¸ā§āϝāĻž āφāϏāĻž. āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇āϰ. āφāϏ⧁āύ āĻāχ āĻŦāĻžāĻ•ā§āϝāĻžāĻ‚āĻļāϟāĻŋ āφāϰ⧇āĻ•āĻŦāĻžāϰ āĻĻ⧇āϖ⧇ āύ⧇āĻ“āϝāĻŧāĻž āϝāĻžāĻ•āĨ¤

āĻāĻ•āϟāĻŋ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āϏāĻžā§āϚāĻžāϞāύāĨ¤

āĻāĻ–āύ āφāĻĒāύāĻŋ āύāĻŋāĻœā§‡āϕ⧇ āĻĒā§āϰāĻļā§āύ āϜāĻŋāĻœā§āĻžāĻžāϏāĻž āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ - āϝāĻĻāĻŋ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻĒāĻŋāĻ›āĻŋāϝāĻŧ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āύāĻž āĻšāϝāĻŧ? āφāĻŽāĻžāϰ āĻ…ā§āϝāĻžāĻĒ⧇āϰ āĻĒā§āϰāĻĨāĻŽ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϟāĻŋ āϭ⧇āϙ⧇ āϝāĻžāĻŦ⧇ āύāĻž? āφāϏāϞ⧇, āĻ āĻŋāĻ• āĻāϟāĻžāχ āĻšāĻŦ⧇...

āϏ⧁āϤāϰāĻžāĻ‚, āĻāĻŽāύāĻ•āĻŋ āĻļā§‚āĻ¨ā§āϝ āĻĄāĻžāωāύāϟāĻžāχāĻŽ / āύ⧀āϞ āϏāĻŦ⧁āϜ āĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϰ āĻŦāĻŋāĻļāĻžāϞ āϏ⧁āĻŦāĻŋāϧāĻž āĻĨāĻžāĻ•āĻž āϏāĻ¤ā§āĻ¤ā§āĻŦ⧇āĻ“, āϕ⧋āĻŽā§āĻĒāĻžāύāĻŋāϗ⧁āϞāĻŋ āϤāĻžāĻĻ⧇āϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻ¸ā§āĻĨāĻžāĻĒāύ⧇āϰ āϜāĻ¨ā§āϝ āύāĻŋāĻŽā§āύāϞāĻŋāĻ–āĻŋāϤ āύāĻŋāϰāĻžāĻĒāĻĻ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰ⧇:

  • āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋāϰ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āϏāĻš āĻāĻ•āϟāĻŋ āĻĒā§āϝāĻžāϕ⧇āϜ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤ āĻ•āϰ⧁āύ
  • āĻāĻ•āϟāĻŋ āϚāϞāĻŽāĻžāύ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻŦāĻ¨ā§āϧ āĻ•āϰ⧁āύ
  • āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻŽāĻžāχāĻ—ā§āϰ⧇āϟ āĻ•āϰāϤ⧇ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āϚāĻžāϞāĻžāύ
  • āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋāϰ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ¸ā§āĻĨāĻžāĻĒāύ āĻāĻŦāĻ‚ āϚāĻžāϞ⧁ āĻ•āϰ⧁āύ

āĻāχ āύāĻŋāĻŦāĻ¨ā§āϧ⧇, āφāĻŽāϰāĻž āĻļā§‚āĻ¨ā§āϝ āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϰ āϏ⧁āĻŦāĻŋāϧāĻž āύāĻŋāϤ⧇ āφāĻĒāύāĻŋ āϕ⧀āĻ­āĻžāĻŦ⧇ āφāĻĒāύāĻžāϰ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻāĻŦāĻ‚ āϕ⧋āĻĄā§‡āϰ āϏāĻžāĻĨ⧇ āĻ•āĻžāϜ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ āϤāĻž āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āϜāĻžāύāĻžāĻŦāĨ¤

āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āϏāĻŽāĻ¸ā§āϝāĻž

āφāĻĒāύāĻžāϰ āϝāĻĻāĻŋ āĻāĻ•āϟāĻŋ āĻ¸ā§āĻŸā§‡āϟāϞ⧇āϏ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻĨāĻžāϕ⧇ āϝāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇ āϕ⧋āύ⧋ āĻĄā§‡āϟāĻž āϏāĻžā§āϚāϝāĻŧ āĻ•āϰ⧇ āύāĻž, āϤāĻžāĻšāϞ⧇ āφāĻĒāύāĻŋ āĻāĻ–āύāχ āĻļā§‚āĻ¨ā§āϝ āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āĻĒ⧇āϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻĻ⧁āĻ°ā§āĻ­āĻžāĻ—ā§āϝāĻŦāĻļāϤ, āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āϏāĻĢā§āϟāĻ“āϝāĻŧā§āϝāĻžāϰāϕ⧇ āϕ⧋āĻĨāĻžāĻ“ āĻĄā§‡āϟāĻž āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ āĻāχ āĻ•āĻžāϰāϪ⧇ āϏāĻžāĻ°ā§āĻ•āĻŋāĻŸā§‡ āϕ⧋āύ⧋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻžāϰ āφāϗ⧇ āφāĻĒāύāĻžāϰ āĻĻ⧁āĻŦāĻžāϰ āϚāĻŋāĻ¨ā§āϤāĻž āĻ•āϰāĻž āωāϚāĻŋāϤāĨ¤ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻ¸ā§āĻ•āĻŋāĻŽāĻž āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāϤ⧇ āĻšāϝāĻŧ āϤāĻžāϰ āĻŦāĻŋāĻļāĻĻ āĻŦāĻŋāĻŦāϰāϪ⧇ āϝāĻžāĻ“āϝāĻŧāĻžāϰ āφāϗ⧇ āϝāĻžāϤ⧇ āύ⧋-āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āϏāĻŽā§āĻ­āĻŦ āĻšāϝāĻŧ, āφāϏ⧁āύ āĻĒā§āϰāĻĨāĻŽā§‡ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ¸ā§āĻ•āĻŋāĻŽāĻžāϰ āωāĻĒāϰ āĻĢā§‹āĻ•āĻžāϏ āĻ•āϰāĻŋāĨ¤

āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ¸ā§āĻ•āĻŋāĻŽ

āĻāχ āύāĻŋāĻŦāĻ¨ā§āϧ⧇ āφāĻŽāϰāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦ āĻĢā§āϞāĻžāχāĻ“āϝāĻŧ⧇ āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āύāĻŋāϝāĻŧāĻ¨ā§āĻ¤ā§āϰāĻŖ āϟ⧁āϞ āĻšāĻŋāϏāĻžāĻŦ⧇ (āĻĒā§āϰāĻžāϝāĻŧ. āĻ…āύ⧁āĻŦāĻžāĻĻ: āφāĻŽāϰāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻ•āĻĨāĻž āĻŦāϞāĻ›āĻŋ) āĻ¸ā§āĻŦāĻžāĻ­āĻžāĻŦāĻŋāĻ•āĻ­āĻžāĻŦ⧇āχ, āφāĻŽāϰāĻž āĻāĻ•āϟāĻŋ āĻ¸ā§āĻĒā§āϰāĻŋāĻ‚ āĻŦ⧁āϟ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāĻ“ āϞāĻŋāĻ–āĻŦ āϝāĻžāϤ⧇ āĻ…āĻ¨ā§āϤāĻ°ā§āύāĻŋāĻ°ā§āĻŽāĻŋāϤ āĻĢā§āϞāĻžāχāĻ“āϝāĻŧ⧇ āϏāĻŽāĻ°ā§āĻĨāύ āϰāϝāĻŧ⧇āϛ⧇ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻĒā§āϰāϏāĻ™ā§āĻ— āϏ⧇āϟ āφāĻĒ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āĻ¸ā§āĻ•āĻŋāĻŽāĻž āĻ¸ā§āĻĨāĻžāύāĻžāĻ¨ā§āϤāϰ āϏāĻŽā§āĻĒāĻžāĻĻāύ āĻ•āϰāĻŦ⧇āĨ¤ āĻĢā§āϞāĻžāχāĻ“āϝāĻŧ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ, āφāĻĒāύāĻŋ āφāĻĒāύāĻžāϰ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ āĻĢā§‹āĻ˛ā§āĻĄāĻžāϰ⧇ āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ (āĻĄāĻŋāĻĢāĻ˛ā§āϟāϰ⧂āĻĒ⧇ classpath:db/migration) āĻāĻ–āĻžāύ⧇ āφāĻĒāύāĻŋ āĻāχ āϧāϰāύ⧇āϰ āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āĻĢāĻžāχāϞ⧇āϰ āωāĻĻāĻžāĻšāϰāĻŖ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāϰ⧇āύ

└── db
 └── migration
     ├── V1__init.sql
     ├── V2__Add_surname.sql
     ├── V3__Final_migration.sql
     └── V4__Remove_lastname.sql

āĻāχ āωāĻĻāĻžāĻšāϰāϪ⧇ āφāĻŽāϰāĻž 4āϟāĻŋ āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻšā§āĻ›āĻŋ āϝ⧇āϗ⧁āϞāĻŋ, āϝāĻĻāĻŋ āφāϗ⧇ āĻ•āĻžāĻ°ā§āϝāĻ•āϰ āĻ•āϰāĻž āύāĻž āĻšāϝāĻŧ, āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻļ⧁āϰ⧁ āĻšāϞ⧇ āĻāϕ⧇āϰ āĻĒāϰ āĻāĻ• āĻ•āĻžāĻ°ā§āϝāĻ•āϰ āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤ āφāϏ⧁āύ āĻāĻ•āϟāĻŋ āĻĢāĻžāχāϞ āĻĻ⧇āĻ–āĻŋ (V1__init.sql) āωāĻĻāĻžāĻšāϰāĻŖ āĻšāĻŋāϏ⧇āĻŦ⧇āĨ¤

CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);

insert into PERSON (first_name, last_name) values ('Dave', 'Syer');

āϏāĻŦāĻ•āĻŋāϛ⧁āχ āĻĒ⧁āϰ⧋āĻĒ⧁āϰāĻŋ āĻ¸ā§āĻŦ-āĻŦā§āϝāĻžāĻ–ā§āϝāĻžāĻŽā§‚āϞāĻ•: āφāĻĒāύāĻžāϰ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āϕ⧀āĻ­āĻžāĻŦ⧇ āϏāĻ‚āĻļā§‹āϧāύ āĻ•āϰāĻž āωāϚāĻŋāϤ āϤāĻž āύāĻŋāĻ°ā§āϧāĻžāϰāĻŖ āĻ•āϰāϤ⧇ āφāĻĒāύāĻŋ SQL āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻ¸ā§āĻĒā§āϰāĻŋāĻ‚ āĻŦ⧁āϟ āĻāĻŦāĻ‚ āĻĢā§āϞāĻžāχāĻ“āϝāĻŧ⧇ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āφāϰāĻ“ āϤāĻĨā§āϝ⧇āϰ āϜāĻ¨ā§āϝ, āĻšā§‡āĻ• āφāωāϟ āĻ•āϰ⧁āύ āĻ¸ā§āĻĒā§āϰāĻŋāĻ‚ āĻŦ⧁āϟ āĻĄāĻ•ā§āϏ.

āĻ¸ā§āĻĒā§āϰāĻŋāĻ‚ āĻŦ⧁āĻŸā§‡āϰ āϏāĻžāĻĨ⧇ āĻāĻ•āϟāĻŋ āĻ‰ā§ŽāϏ āύāĻŋāϝāĻŧāĻ¨ā§āĻ¤ā§āϰāĻŖ āϟ⧁āϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇, āφāĻĒāύāĻŋ 2āϟāĻŋ āĻŦāĻĄāĻŧ āϏ⧁āĻŦāĻŋāϧāĻž āĻĒāĻžāĻŦ⧇āύ:

  • āφāĻĒāύāĻŋ āϕ⧋āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻĨ⧇āϕ⧇ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻĒ⧃āĻĨāĻ•
  • āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ⧇āϰ āϰ⧋āϞāφāωāĻŸā§‡āϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ āĻĄā§‡āϟāĻžāĻŦ⧇āϏ āĻ¸ā§āĻĨāĻžāύāĻžāĻ¨ā§āϤāϰ āϘāĻŸā§‡, āϝ⧇āĻŽāύ āφāĻĒāύāĻžāϰ āĻ¸ā§āĻĨāĻžāĻĒāύ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻž āϏāϰāϞ⧀āĻ•ā§ƒāϤ āĻšāϝāĻŧ

āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇āϰ āϏāĻŽāĻ¸ā§āϝāĻž āϏāĻŽāĻžāϧāĻžāύ āĻ•āϰāĻž

āύāĻŋāĻŦāĻ¨ā§āϧ⧇āϰ āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āĻŦāĻŋāĻ­āĻžāϗ⧇, āφāĻŽāϰāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ⧇āϰ āĻĻ⧁āϟāĻŋ āĻĒāĻĻā§āϧāϤāĻŋāϰ āĻĻāĻŋāϕ⧇ āύāϜāϰ āĻĻ⧇āĻŦāĨ¤

  • āĻĒāĻļā§āϚāĻžāĻĻāĻ—āĻžāĻŽā§€ āĻ…āϏāĻ™ā§āĻ—āϤāĻŋ
  • āĻ…āύāĻ…āĻ—ā§āϰāϏāϰ āωāĻĒāϝ⧋āĻ—āĻŋāϤāĻž

āĻĒā§āϰāĻĨāĻŽāϟāĻŋ āĻāĻ•āϟāĻŋ āϏāϤāĻ°ā§āĻ•āϤāĻž āĻšāĻŋāϏāĻžāĻŦ⧇ āĻŦāĻŋāĻŦ⧇āϚāĻŋāϤ āĻšāĻŦ⧇ āϝ⧇ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ• āĻĒā§āϰāĻ¸ā§āϤ⧁āϤāĻŋ āĻ›āĻžāĻĄāĻŧāĻž āφāĻĒāύāĻžāϰ āĻļā§‚āĻ¨ā§āϝ āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āϏāĻžā§āϚāĻžāϞāύ āĻ•āϰāĻž āωāϚāĻŋāϤ āύāϝāĻŧ... āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧāϟāĻŋ āϕ⧀āĻ­āĻžāĻŦ⧇ āφāĻĒāύāĻŋ āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ›āĻžāĻĄāĻŧāĻžāχ āĻāĻ•āϟāĻŋ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āϏāĻŽā§āĻĒāĻžāĻĻāύ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ āĻāĻŦāĻ‚ āĻāĻ•āχ āϏāĻžāĻĨ⧇ āĻĒāĻļā§āϚāĻžāĻĻāĻŽā§āĻ–ā§€ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ āĻŦāϜāĻžāϝāĻŧ āϰāĻžāĻ–āϤ⧇ āĻĒāĻžāϰ⧇āύ āϤāĻžāϰ āĻāĻ•āϟāĻŋ āϏāĻŽāĻžāϧāĻžāύ āĻĒā§āϰāĻ¸ā§āϤāĻžāĻŦ āĻ•āϰ⧇⧎

āφāĻŽāĻžāĻĻ⧇āϰ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ⧇ āφāĻŽāϰāĻž āĻ•āĻžāϜ āĻ•āϰāĻŦ āĻāĻ•āϟāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āĻ¸ā§āĻĒā§āϰāĻŋāĻ‚ āĻŦ⧁āϟ āĻĢā§āϞāĻžāχāĻ“āϝāĻŧ⧇ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϝāĻž āϰāϝāĻŧ⧇āϛ⧇ Person ҁ first_name и last_name āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇ (āĻĒā§āϰāĻžāϝāĻŧ. āĻ…āύ⧁āĻŦāĻžāĻĻ: Person āĻāĻ•āϟāĻŋ āĻŸā§‡āĻŦāĻŋāϞ āĻāĻŦāĻ‚ āϚirst_name и last_name - āĻāχ āĻšāϞ āĻāϟāĻŋāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ) āφāĻŽāϰāĻž āύāĻžāĻŽ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāϤ⧇ āϚāĻžāχ last_name в surname.

āĻ…āύ⧁āĻŽāĻžāύ

āφāĻŽāϰāĻž āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āϜāĻžāύāĻžāϰ āφāϗ⧇, āφāĻŽāĻžāĻĻ⧇āϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϗ⧁āϞāĻŋ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻ•āϝāĻŧ⧇āĻ•āϟāĻŋ āĻ…āύ⧁āĻŽāĻžāύ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ āĻŽā§‚āϞ āĻĢāϞāĻžāĻĢāϞ āϝāĻž āφāĻŽāϰāĻž āĻ…āĻ°ā§āϜāύ āĻ•āϰāϤ⧇ āϚāĻžāχ āϤāĻž āĻšāĻŦ⧇ āĻāĻ•āϟāĻŋ āĻŽā§‹āϟāĻžāĻŽā§āϟāĻŋ āϏāĻšāϜ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻžāĨ¤

āύ⧋āϟ. āĻŦāĻŋāϜāύ⧇āϏ āĻĒā§āϰ⧋-āϟāĻŋāĻĒāĨ¤ āϏāĻšāĻœā§€āĻ•āϰāĻŖ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻžāϗ⧁āϞāĻŋ āφāĻĒāύāĻžāϕ⧇ āϏāĻŽāĻ°ā§āĻĨāύ⧇ āĻĒā§āϰāϚ⧁āϰ āĻ…āĻ°ā§āĻĨ āϏāĻžāĻļā§āϰāϝāĻŧ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇ (āφāĻĒāύāĻžāϰ āϕ⧋āĻŽā§āĻĒāĻžāύāĻŋāϰ āϜāĻ¨ā§āϝ āφāĻĒāύāĻŋ āϝāϤ āĻŦ⧇āĻļāĻŋ āϞ⧋āĻ• āĻ•āĻžāϜ āĻ•āϰāĻŦ⧇āύ, āφāĻĒāύāĻŋ āϤāϤ āĻŦ⧇āĻļāĻŋ āĻ…āĻ°ā§āĻĨ āϏāĻžā§āϚāϝāĻŧ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύ)!

āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āϰ⧋āϞāĻŦā§āϝāĻžāĻ• āĻ•āϰāĻžāϰ āĻĻāϰāĻ•āĻžāϰ āύ⧇āχ

āĻāϟāĻŋ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻžāϕ⧇ āϏāĻšāϜ āĻ•āϰ⧇ (āĻ•āĻŋāϛ⧁ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āϰ⧋āϞāĻŦā§āϝāĻžāĻ• āĻĒā§āϰāĻžāϝāĻŧ āĻ…āϏāĻŽā§āĻ­āĻŦ, āϝ⧇āĻŽāύ āĻŽā§‹āĻ›āĻž āϰ⧋āϞāĻŦā§āϝāĻžāĻ•)āĨ¤ āφāĻŽāϰāĻž āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϰ⧋āϞ āĻŦā§āϝāĻžāĻ• āĻ•āϰāϤ⧇ āĻĒāĻ›āĻ¨ā§āĻĻ āĻ•āϰāĻŋāĨ¤ āĻāχāĻ­āĻžāĻŦ⧇, āĻāĻŽāύāĻ•āĻŋ āϝāĻĻāĻŋ āφāĻĒāύāĻžāϰ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĨāĻžāϕ⧇ (āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, SQL āĻāĻŦāĻ‚ NoSQL), āφāĻĒāύāĻžāϰ āĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϰ āĻĒāĻžāχāĻĒāϞāĻžāχāύ āĻāĻ•āχ āĻĻ⧇āĻ–āĻžāĻŦ⧇āĨ¤

āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāĻžāύāϟāĻŋāϕ⧇ āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻĢāĻŋāϰāĻŋāϝāĻŧ⧇ āφāύāĻžāϰ āϜāĻ¨ā§āϝ āϏāĻ°ā§āĻŦāĻĻāĻž āϏāĻŽā§āĻ­āĻŦ āĻšāϤ⧇ āĻšāĻŦ⧇ (āφāϰ āĻ•āĻŋāϛ⧁ āύāϝāĻŧ)

āϰ⧋āϞāĻŦā§āϝāĻžāĻ• āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻšāϞ⧇āχ āĻ•āϰāĻž āωāϚāĻŋāϤāĨ¤ āϝāĻĻāĻŋ āĻŦāĻ°ā§āϤāĻŽāĻžāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ āĻāĻ•āϟāĻŋ āĻŦāĻžāĻ— āĻĨāĻžāϕ⧇ āϝāĻž āϏāĻšāĻœā§‡ āĻ āĻŋāĻ• āĻ•āϰāĻž āϝāĻžāϝāĻŧ āύāĻž, āϤāĻžāĻšāϞ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āϏāĻ°ā§āĻŦāĻļ⧇āώ āĻ•āĻžāĻ°ā§āϝāĻ•āϰ⧀ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āϏāĻ•ā§āώāĻŽ āĻšāĻ“āϝāĻŧāĻž āωāϚāĻŋāϤāĨ¤ āφāĻŽāϰāĻž āϧāϰ⧇ āύāĻŋāχ āϝ⧇ āĻāχ āϏāĻ°ā§āĻŦāĻļ⧇āώ āĻ•āĻžāĻ°ā§āϝāĻ•āϰ⧀ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϟāĻŋ āφāϗ⧇āϰāϟāĻŋāĨ¤ āĻāĻ•āĻžāϧāĻŋāĻ• āϰ⧋āϞāφāωāĻŸā§‡āϰ āϜāĻ¨ā§āϝ āϕ⧋āĻĄ āĻāĻŦāĻ‚ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ āĻŦāϜāĻžāϝāĻŧ āϰāĻžāĻ–āĻž āĻ…āĻ¤ā§āϝāĻ¨ā§āϤ āĻ•āĻ āĻŋāύ āĻāĻŦāĻ‚ āĻŦā§āϝāϝāĻŧāĻŦāĻšā§āϞ āĻšāĻŦ⧇āĨ¤

āύ⧋āϟ. āĻŦ⧃āĻšāĻ¤ā§āϤāϰ āĻĒāĻžāĻ āϝ⧋āĻ—ā§āϝāϤāĻžāϰ āϜāĻ¨ā§āϝ, āĻāχ āύāĻŋāĻŦāĻ¨ā§āϧ⧇ āφāĻŽāϰāĻž āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋāϰ āĻĒā§āϰāϧāĻžāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻŦāĨ¤

āϧāĻžāĻĒ 1: āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ• āĻ…āĻŦāĻ¸ā§āĻĨāĻž

āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ: 1.0.0
āĻĄāĻŋāĻŦāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ: v1

āĻŽāĻ¨ā§āϤāĻŦā§āϝ

āĻāϟāĻŋ āĻšāĻŦ⧇ āφāĻŦ⧇āĻĻāύ⧇āϰ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ• āĻ…āĻŦāĻ¸ā§āĻĨāĻžāĨ¤

āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

āĻĄāĻŋāĻŦāĻŋ āϧāĻžāϰāĻŖ āĻ•āϰ⧇ last_name.

CREATE TABLE PERSON (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY,
    first_name varchar(255) not null,
    last_name varchar(255) not null
);

insert into PERSON (first_name, last_name) values ('Dave', 'Syer');

āϕ⧋āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻŦā§āϝāĻ•ā§āϤāĻŋ āϤāĻĨā§āϝ āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰ⧇ last_name:

/*
 * Copyright 2012-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sample.flyway;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private String firstName;
    private String lastName;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastname) {
        this.lastName = lastname;
    }

    @Override
    public String toString() {
        return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName
                + "]";
    }
}

āĻĒāĻŋāĻ›āύ⧇āϰ āĻĻāĻŋāϕ⧇ āĻŦ⧇āĻŽāĻžāύāĻžāύ āĻ•āϞāĻžāĻŽ āĻĒ⧁āύāσāύāĻžāĻŽāĻ•āϰāĻŖ

āφāϏ⧁āύ āĻāĻ•āϟāĻŋ āĻ•āϞāĻžāĻŽā§‡āϰ āύāĻžāĻŽ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāϤ⧇ āĻšāϝāĻŧ āϤāĻžāϰ āĻāĻ•āϟāĻŋ āωāĻĻāĻžāĻšāϰāĻŖ āĻĻ⧇āĻ–āĻŋ:

āĻŽāύ⧋āϝ⧋āĻ—. āύāĻŋāĻŽā§āύāϞāĻŋāĻ–āĻŋāϤ āωāĻĻāĻžāĻšāϰāĻŖ āχāĻšā§āĻ›āĻžāĻ•ā§ƒāϤāĻ­āĻžāĻŦ⧇ āϜāĻŋāύāĻŋāϏ āĻ­āĻžāĻ™ā§āĻ—āĻž āĻšāĻŦ⧇. āφāĻŽāϰāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ⧇āϰ āϏāĻŽāĻ¸ā§āϝāĻž āĻĒā§āϰāĻĻāĻ°ā§āĻļāύ āĻ•āϰāϤ⧇ āĻāϟāĻŋ āĻĻ⧇āĻ–āĻžāχāĨ¤

āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ: 2.0.0.BAD

āĻĄāĻŋāĻŦāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ: v2bad

āĻŽāĻ¨ā§āϤāĻŦā§āϝ

āĻŦāĻ°ā§āϤāĻŽāĻžāύ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύāϗ⧁āϞāĻŋ āφāĻŽāĻžāĻĻ⧇āϰ āĻāĻ•āχ āϏāĻŽāϝāĻŧ⧇ āĻĻ⧁āϟāĻŋ āωāĻĻāĻžāĻšāϰāĻŖ (āĻĒ⧁āϰāĻžāύ⧋ āĻāĻŦāĻ‚ āύāϤ⧁āύ) āϚāĻžāϞāĻžāύ⧋āϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻ⧇āϝāĻŧ āύāĻžāĨ¤ āϏ⧁āϤāϰāĻžāĻ‚, āĻļā§‚āĻ¨ā§āϝ āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āĻ…āĻ°ā§āϜāύ āĻ•āϰāĻž āĻ•āĻ āĻŋāύ āĻšāĻŦ⧇ (āϝāĻĻāĻŋ āĻ…āύ⧁āĻŽāĻžāύāϗ⧁āϞāĻŋ āĻŦāĻŋāĻŦ⧇āϚāύāĻžāϝāĻŧ āύ⧇āĻ“āϝāĻŧāĻž āĻšāϝāĻŧ āϤāĻŦ⧇ āĻāϟāĻŋ āφāϏāϞ⧇ āĻ…āϏāĻŽā§āĻ­āĻŦ)āĨ¤

A/B āĻĒāϰ⧀āĻ•ā§āώāĻž

āĻŦāĻ°ā§āϤāĻŽāĻžāύ āĻĒāϰāĻŋāĻ¸ā§āĻĨāĻŋāϤāĻŋ āφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϛ⧇ āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āϰāϝāĻŧ⧇āϛ⧇ 1.0.0, āĻ‰ā§ŽāĻĒāĻžāĻĻāύ, āĻāĻŦāĻ‚ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇ āĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇ v1. āφāĻŽāĻžāĻĻ⧇āϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ, āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇āϰ āĻāĻ•āϟāĻŋ āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āĻĻ⧃āĻˇā§āϟāĻžāĻ¨ā§āϤ āĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ 2.0.0.BAD, āĻāĻŦāĻ‚ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āφāĻĒāĻĄā§‡āϟ āĻ•āϰ⧁āύ v2bad.

āϧāĻžāĻĒ:

  1. āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ⧇āϰ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āωāĻĻāĻžāĻšāϰāĻŖ āĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇ 2.0.0.BADāϝāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āφāĻĒāĻĄā§‡āϟ āĻ•āϰ⧇ v2bad
  2. āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇ v2bad āĻ¸ā§āϤāĻŽā§āĻ­ last_name āφāϰ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āύ⧇āχ - āĻāϟāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāĻŋāϤ āĻšāϝāĻŧ⧇āϛ⧇⧎ surname
  3. āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āφāĻĒāĻĄā§‡āϟ āϏāĻĢāϞ āĻšāϝāĻŧ⧇āϛ⧇ āĻāĻŦāĻ‚ āĻ•āĻŋāϛ⧁ āĻĻ⧃āĻˇā§āϟāĻžāĻ¨ā§āϤ āϚāϞāϛ⧇ 1.0.0, āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ - āĻŽāĻ§ā§āϝ⧇ 2.0.0.BAD. āϏāĻŦāĻ•āĻŋāϛ⧁ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇āϰ āϏāĻžāĻĨ⧇ āϏāĻ‚āϝ⧁āĻ•ā§āϤ v2bad
  4. āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇āϰ āϏāĻŽāĻ¸ā§āϤ āωāĻĻāĻžāĻšāϰāĻŖ 1.0.0 āϤāĻžāϰāĻž āĻ•āϞāĻžāĻŽā§‡ āϤāĻĨā§āϝ āϏāĻ¨ā§āύāĻŋāĻŦ⧇āĻļ āĻ•āϰāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĻŦ⧇ āĻ•āĻžāϰāĻŖ āĻ¤ā§āϰ⧁āϟāĻŋ āύāĻŋāĻ•ā§āώ⧇āĻĒ āĻ•āϰāĻž āĻļ⧁āϰ⧁ āĻ•āϰāĻŦ⧇ last_nameāϝāĻžāϰāĻž āφāϰ āύ⧇āχ
  5. āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇āϰ āϏāĻŽāĻ¸ā§āϤ āωāĻĻāĻžāĻšāϰāĻŖ 2.0.0.BAD āϏāĻŽāĻ¸ā§āϝāĻž āĻ›āĻžāĻĄāĻŧāĻžāχ āĻ•āĻžāϜ āĻ•āϰāĻŦ⧇

āφāĻĒāύāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻšā§āϛ⧇āύ, āϝāĻĻāĻŋ āφāĻŽāϰāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ⧇ āĻ…āϏāĻ™ā§āĻ—āϤāĻŋāĻĒā§‚āĻ°ā§āĻŖ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻŋ, āϤāĻžāĻšāϞ⧇ A/B āĻĒāϰ⧀āĻ•ā§āώāĻž āĻ•āϰāĻž āĻ…āϏāĻŽā§āĻ­āĻŦāĨ¤

āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϰ⧋āϞāĻŦā§āϝāĻžāĻ•

āϧāϰāĻž āϝāĻžāĻ• A/B āĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĻžāϰ āĻĒāϰ⧇ (āĻĒā§āϰāĻžāϝāĻŧ. āĻĒā§āϰāϤāĻŋ.: āϞ⧇āĻ–āĻ• āϏāĻŽā§āĻ­āĻŦāϤ āĻāĻ–āĻžāύ⧇ A/B āĻĒāϰ⧀āĻ•ā§āώāĻž āĻŦā§‹āĻāĻžāϤ⧇ āĻšā§‡āϝāĻŧ⧇āϛ⧇āύ) āφāĻŽāϰāĻž āϏāĻŋāĻĻā§āϧāĻžāĻ¨ā§āϤ āύāĻŋāϝāĻŧ⧇āĻ›āĻŋ āϝ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋāϕ⧇ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ āĻĢāĻŋāϰāĻŋāϝāĻŧ⧇ āφāύāϤ⧇ āĻšāĻŦ⧇ 1.0.0. āϧāϰāĻž āϝāĻžāĻ• āφāĻŽāϰāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āϰ⧋āϞāĻŦā§āϝāĻžāĻ• āĻ•āϰāϤ⧇ āϚāĻžāχ āύāĻžāĨ¤

āϧāĻžāĻĒ:

  1. āφāĻŽāϰāĻž āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āωāĻĻāĻžāĻšāϰāĻŖ āĻŦāĻ¨ā§āϧ 2.0.0.BAD
  2. āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻāĻ–āύāĻ“ āφāϛ⧇ v2bad
  3. āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻĨ⧇āϕ⧇ 1.0.0 āĻāϟāĻž āĻ•āĻŋ āĻŦ⧁āĻāϤ⧇ āĻĒāĻžāϰ⧇ āύāĻž surname, āφāĻŽāϰāĻž āĻ¤ā§āϰ⧁āϟāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ
  4. āϜāĻžāĻšāĻžāĻ¨ā§āύāĻžāĻŽ āϭ⧇āϙ⧇ āϗ⧇āϛ⧇, āφāĻŽāϰāĻž āφāϰ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻĒāĻžāϰāĻŋ āύāĻž

āφāĻĒāύāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻšā§āϛ⧇āύ, āϝāĻĻāĻŋ āφāĻŽāϰāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ⧇ āĻ…āϏāĻ™ā§āĻ—āϤāĻŋāĻĒā§‚āĻ°ā§āĻŖ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻŋ, āφāĻŽāϰāĻž āĻĒā§‚āĻ°ā§āĻŦāĻŦāĻ°ā§āϤ⧀ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ āĻĢāĻŋāϰ⧇ āϝ⧇āϤ⧇ āĻĒāĻžāϰāĻŋ āύāĻžāĨ¤

āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻāĻ•ā§āϏāĻŋāĻ•āĻŋāωāĻļāύ āϞāĻ—

Backward incompatible scenario:

01) Run 1.0.0
02) Wait for the app (1.0.0) to boot
03) Generate a person by calling POST localhost:9991/person to version 1.0.0
04) Run 2.0.0.BAD
05) Wait for the app (2.0.0.BAD) to boot
06) Generate a person by calling POST localhost:9991/person to version 1.0.0 <-- this should fail
07) Generate a person by calling POST localhost:9992/person to version 2.0.0.BAD <-- this should pass

Starting app in version 1.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

{"firstName":"b73f639f-e176-4463-bf26-1135aace2f57","lastName":"b73f639f-e176-4463-bf26-1135aace2f57"}

Starting app in version 2.0.0.BAD
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

curl: (22) The requested URL returned error: 500 Internal Server Error

Generate a person in version 2.0.0.BAD
Sending a post to 127.0.0.1:9995/person. This is the response:

{"firstName":"e156be2e-06b6-4730-9c43-6e14cfcda125","surname":"e156be2e-06b6-4730-9c43-6e14cfcda125"}

āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āϝāĻž āύāĻžāĻŽ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧇ last_name в surname

āωāĻ¤ā§āϏ āĻĢā§āϞāĻžāχāĻ“āϝāĻŧ⧇ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ:

CREATE TABLE PERSON (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY,
    first_name varchar(255) not null,
    last_name varchar(255) not null
);

insert into PERSON (first_name, last_name) values ('Dave', 'Syer');

āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āϝ⧇ āύāĻžāĻŽ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ last_name.

-- This change is backward incompatible - you can't do A/B testing
ALTER TABLE PERSON CHANGE last_name surname VARCHAR;

āϕ⧋āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

āφāĻŽāϰāĻž āĻŽāĻžāϠ⧇āϰ āύāĻžāĻŽ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧇āĻ›āĻŋ lastName āωāĻĒāϰ surname.

āĻĒāĻŋāĻ›āύ⧇āϰ-āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āωāĻĒāĻžāϝāĻŧ⧇ āĻāĻ•āϟāĻŋ āĻ•āϞāĻžāĻŽā§‡āϰ āύāĻžāĻŽ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž

āĻāϟāĻŋ āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āϏāĻžāϧāĻžāϰāĻŖ āĻĒāϰāĻŋāĻ¸ā§āĻĨāĻŋāϤāĻŋ āϝāĻž āφāĻŽāϰāĻž āϏāĻŽā§āĻŽā§āĻ–ā§€āύ āĻšāϤ⧇ āĻĒāĻžāϰāĻŋāĨ¤ āφāĻŽāĻžāĻĻ⧇āϰ āĻĒāĻŋāĻ›āύ⧇āϰ āĻĻāĻŋāϕ⧇ āĻŦ⧇āĻŽāĻžāύāĻžāύ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ āφāĻŽāϰāĻž āχāϤāĻŋāĻŽāĻ§ā§āϝ⧇āχ āĻĒā§āϰāĻŽāĻžāĻŖ āĻ•āϰ⧇āĻ›āĻŋ āϝ⧇ āĻļā§‚āĻ¨ā§āϝ-āĻĄāĻžāωāύāϟāĻžāχāĻŽ āĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϰ āϜāĻ¨ā§āϝ, āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻĒāĻĻāĻ•ā§āώ⧇āĻĒ āĻ›āĻžāĻĄāĻŧāĻžāχ āφāĻŽāĻžāĻĻ⧇āϰ āϕ⧇āĻŦāϞ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āĻĒā§āϰāϝāĻŧā§‹āĻ— āĻ•āϰāĻž āωāϚāĻŋāϤ āύāϝāĻŧāĨ¤ āύāĻŋāĻŦāĻ¨ā§āϧ⧇āϰ āĻāχ āĻŦāĻŋāĻ­āĻžāϗ⧇, āφāĻŽāϰāĻž āĻ…āύāĻ—ā§āϰāϏāϰ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ āĻŦāϜāĻžāϝāĻŧ āϰ⧇āϖ⧇ āĻ•āĻžāĻ™ā§āĻ•ā§āώāĻŋāϤ āĻĢāϞāĻžāĻĢāϞ āĻ…āĻ°ā§āϜāύ⧇āϰ āϜāĻ¨ā§āϝ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻ¸ā§āĻĨāĻžāύāĻžāĻ¨ā§āϤāϰ āϏāĻš āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋāϰ 3āϟāĻŋ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āϏāĻŽā§āĻĒāĻžāĻĻāύ āĻ•āϰāĻŦāĨ¤

āύ⧋āϟ. āĻŽāύ⧇ āϰāĻžāĻ–āĻŦ⧇āύ āϝ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āφāϛ⧇ v1. āĻāϤ⧇ āĻ•āϞāĻžāĻŽ āϰāϝāĻŧ⧇āϛ⧇ first_name и last_name. āφāĻŽāĻžāĻĻ⧇āϰ āĻŦāĻĻāϞāĻžāϤ⧇ āĻšāĻŦ⧇ last_name āωāĻĒāϰ surname. āφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϛ⧇ āĻ…ā§āϝāĻžāĻĒ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāĻ“ āϰāϝāĻŧ⧇āϛ⧇ 1.0.0, āϝāĻž āĻāĻ–āύ⧋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšāϝāĻŧāύāĻŋ surname.

āϧāĻžāĻĒ 2: āωāĻĒāĻžāϧāĻŋ āϝ⧋āĻ— āĻ•āϰ⧁āύ

āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ: 2.0.0
āĻĄāĻŋāĻŦāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ: v2

āĻŽāĻ¨ā§āϤāĻŦā§āϝ

āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āĻ•āϞāĻžāĻŽ āϝ⧋āĻ— āĻ•āϰ⧇ āĻāĻŦāĻ‚ āĻāϰ āĻŦāĻŋāώāϝāĻŧāĻŦāĻ¸ā§āϤ⧁ āĻ…āύ⧁āϞāĻŋāĻĒāĻŋ āĻ•āϰ⧇, āφāĻŽāϰāĻž āĻĒāĻŋāĻ›āύ⧇āϰ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύāϗ⧁āϞāĻŋ āϤ⧈āϰāĻŋ āĻ•āϰāĻŋāĨ¤ āĻāĻ•āχ āϏāĻŽāϝāĻŧ⧇, āϝāĻĻāĻŋ āφāĻŽāϰāĻž JAR āϰ⧋āϞāĻŦā§āϝāĻžāĻ• āĻ•āϰāĻŋ āĻŦāĻž āĻāĻ•āϟāĻŋ āĻĒ⧁āϰāĻžāύ⧋ JAR āϚāϞāĻŽāĻžāύ āĻĨāĻžāϕ⧇ āϤāĻŦ⧇ āĻāϟāĻŋ āĻ•āĻžāĻ°ā§āϝāĻ•āϰ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āϭ⧇āϙ⧇ āϝāĻžāĻŦ⧇ āύāĻžāĨ¤

āφāĻŽāϰāĻž āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āϰ⧋āϞ āφāωāϟ āĻ•āϰāĻ›āĻŋ

āϧāĻžāĻĒ:

  1. āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āĻ•āϞāĻžāĻŽ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻāĻ•āϟāĻŋ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻ¸ā§āĻĨāĻžāύāĻžāĻ¨ā§āϤāϰ āĻ•āϰ⧁āύ surname. āĻāĻ–āύ āφāĻĒāύāĻžāϰ āĻĄāĻŋāĻŦāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ v2
  2. āĻĨ⧇āϕ⧇ āĻĄā§‡āϟāĻž āĻ…āύ⧁āϞāĻŋāĻĒāĻŋ āĻ•āϰ⧁āύ last_name в surname. āĻŽāύ⧋āϝ⧋āĻ— āĻĻāĻžāĻ“āϝāĻĻāĻŋ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ āĻāχ āĻĄā§‡āϟāĻž āĻ…āύ⧇āĻ• āĻĨāĻžāϕ⧇ āϤāĻŦ⧇ āφāĻĒāύāĻžāϰ āĻŦā§āϝāĻžāϚ āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āĻŦāĻŋāĻŦ⧇āϚāύāĻž āĻ•āϰāĻž āωāϚāĻŋāϤ!
  3. āϕ⧋āĻĄ āϞāĻŋāϖ⧁āύ āϝ⧇āĻ–āĻžāύ⧇ āϤāĻžāϰāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšāϝāĻŧ āωāĻ­āϝāĻŧ и ĐŊĐžĐ˛Ņ‹ĐšāĻāĻŦāĻ‚ āĻĒ⧁āϰāĻžāϤāύ āĻ•āϞāĻžāĻŽ āĻāĻ–āύ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ 2.0.0
  4. āĻ•āϞāĻžāĻŽ āĻĨ⧇āϕ⧇ āĻŽāĻžāύ āĻĒāĻĄāĻŧ⧁āύ surname, āϝāĻĻāĻŋ āϤāĻž āύāĻž āĻšāϝāĻŧ null, āĻ…āĻĨāĻŦāĻž l āĻĨ⧇āϕ⧇ast_nameāϝāĻĻāĻŋ surname āωāĻ˛ā§āϞāĻŋāĻ–āĻŋāϤ āύāĻž. āφāĻĒāύāĻŋ āĻŽā§āϛ⧇ āĻĻāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āύ getLastName() āϕ⧋āĻĄ āĻĨ⧇āϕ⧇, āϝ⧇āĻšā§‡āϤ⧁ āĻāϟāĻŋ āφāωāϟāĻĒ⧁āϟ āĻšāĻŦ⧇ null āĻĨ⧇āϕ⧇ āφāĻĒāύāĻžāϰ āφāĻŦ⧇āĻĻāύ āϰ⧋āϞ āĻŦā§āϝāĻžāĻ• āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ 3.0.0 āĻĨ⧇āϕ⧇ 2.0.0.

āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻ¸ā§āĻĒā§āϰāĻŋāĻ‚ āĻŦ⧁āϟ āĻĢā§āϞāĻžāχāĻ“āϝāĻŧ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āύ, āĻāχ āĻĻ⧁āϟāĻŋ āĻĒāĻĻāĻ•ā§āώ⧇āĻĒ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ¸ā§āϟāĻžāĻ°ā§āϟāφāĻĒ⧇āϰ āϏāĻŽāϝāĻŧ āϏāĻžā§āϚāĻžāϞāĻŋāϤ āĻšāĻŦ⧇ 2.0.0 āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āϏāϰāĻžā§āϜāĻžāĻŽāϟāĻŋ āĻŽā§āϝāĻžāύ⧁āϝāĻŧāĻžāϞāĻŋ āϚāĻžāϞāĻžāύ āϤāĻŦ⧇ āĻāϟāĻŋ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āφāĻĒāύāĻžāϕ⧇ āĻĻ⧁āϟāĻŋ āĻ­āĻŋāĻ¨ā§āύ āϜāĻŋāύāĻŋāϏ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ (āĻĒā§āϰāĻĨāĻŽā§‡ āĻĄāĻŋāĻŦāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϟāĻŋ āĻŽā§āϝāĻžāύ⧁āϝāĻŧāĻžāϞāĻŋ āφāĻĒāĻĄā§‡āϟ āĻ•āϰ⧁āύ āĻāĻŦāĻ‚ āϤāĻžāϰāĻĒāϰ⧇ āύāϤ⧁āύ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰ⧁āύ)āĨ¤

āĻāϟāĻž āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖāĨ¤ āĻŽāύ⧇ āϰāĻžāĻ–āĻŦ⧇āύ āϝ⧇ āϏāĻĻā§āϝ āύāĻŋāĻ°ā§āĻŽāĻŋāϤ āĻ•āϞāĻžāĻŽ āωāϚāĻŋāϤ āύāϝāĻŧ āĻšāϤ⧇ āĻšāĻŦ⧇ āύāĻžāϞ āύāĻž. āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻāĻ•āϟāĻŋ āϰ⧋āϞāĻŦā§āϝāĻžāĻ• āĻ•āϰ⧇āύ, āĻĒ⧁āϰāĻžāύ⧋ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋ āύāϤ⧁āύ āĻ•āϞāĻžāĻŽ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āϜāĻžāύ⧇ āύāĻž āĻāĻŦāĻ‚ āĻāϟāĻŋāϰ āϏāĻŽāϝāĻŧ āĻāϟāĻŋ āχāύāĻ¸ā§āϟāϞ āĻ•āϰāĻŦ⧇ āύāĻž Insert. āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻāχ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž āϝ⧋āĻ— āĻ•āϰ⧇āύ āĻāĻŦāĻ‚ āφāĻĒāύāĻžāϰ āĻĄāĻŋāĻŦāĻŋ āĻšāĻŦ⧇ v2, āĻāϰ āϜāĻ¨ā§āϝ āύāϤ⧁āύ āĻ•āϞāĻžāĻŽā§‡āϰ āĻŽāĻžāύ āύāĻŋāĻ°ā§āϧāĻžāϰāĻŖ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ āϝāĻž āĻŦāĻŋāϧāĻŋāύāĻŋāώ⧇āϧ āϞāĻ™ā§āϘāύ⧇āϰ āĻĻāĻŋāϕ⧇ āύāĻŋāϝāĻŧ⧇ āϝāĻžāĻŦ⧇āĨ¤

āĻāϟāĻž āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖāĨ¤ āφāĻĒāύāĻŋ āĻĒāĻĻā§āϧāϤāĻŋ āĻ…āĻĒāϏāĻžāϰāĻŖ āĻ•āϰāĻž āωāϚāĻŋāϤ getLastName(), āĻ•āĻžāϰāĻŖ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ 3.0.0 āϕ⧋āĻĄā§‡ āĻāĻ•āϟāĻŋ āĻ•āϞāĻžāĻŽā§‡āϰ āϕ⧋āύ āϧāĻžāϰāĻŖāĻž āύ⧇āχ last_name. āĻāϰ āĻŽāĻžāύ⧇ āϏ⧇āĻ–āĻžāύ⧇ āύāĻžāϞ āϏ⧇āϟ āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤ āφāĻĒāύāĻŋ āĻĒāĻĻā§āϧāϤāĻŋāϟāĻŋ āϛ⧇āĻĄāĻŧ⧇ āĻĻāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āύ āĻāĻŦāĻ‚ āĻāϰ āϜāĻ¨ā§āϝ āĻšā§‡āĻ• āϝ⧋āĻ— āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ null, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāĻ•āϟāĻŋ āĻ…āύ⧇āĻ• āĻ­āĻžāϞ āϏāĻŽāĻžāϧāĻžāύ āϝ⧁āĻ•ā§āϤāĻŋāϤ⧇ āϤāĻž āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰāĻž āĻšāĻŦ⧇ getSurname() āφāĻĒāύāĻŋ āϏāĻ āĻŋāĻ• āĻ…-āĻļā§‚āĻ¨ā§āϝ āĻŽāĻžāύ āύāĻŋāĻ°ā§āĻŦāĻžāϚāύ āĻ•āϰ⧇āϛ⧇āύāĨ¤

A/B āĻĒāϰ⧀āĻ•ā§āώāĻž

āĻŦāĻ°ā§āϤāĻŽāĻžāύ āĻĒāϰāĻŋāĻ¸ā§āĻĨāĻŋāϤāĻŋ āφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϛ⧇ āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āϰāϝāĻŧ⧇āϛ⧇ 1.0.0, āĻ‰ā§ŽāĻĒāĻžāĻĻāύ⧇ āύāĻŋāϝāĻŧā§‹āϜāĻŋāϤ, āĻāĻŦāĻ‚ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻāϰ āĻŽāĻ§ā§āϝ⧇ v1. āφāĻŽāĻžāĻĻ⧇āϰ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋāϰ āĻāĻ•āϟāĻŋ āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āĻĻ⧃āĻˇā§āϟāĻžāĻ¨ā§āϤ āĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ 2.0.0āϝāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āφāĻĒāĻĄā§‡āϟ āĻ•āϰāĻŦ⧇ v2.

āϧāĻžāĻĒ:

  1. āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ⧇āϰ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āωāĻĻāĻžāĻšāϰāĻŖ āĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇ 2.0.0āϝāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āφāĻĒāĻĄā§‡āϟ āĻ•āϰ⧇ v2
  2. āχāϤāĻŋāĻŽāĻ§ā§āϝ⧇ āĻ•āĻŋāϛ⧁ āĻ…āύ⧁āϰ⧋āϧ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻĻ⧃āĻˇā§āϟāĻžāĻ¨ā§āϤ āĻĻā§āĻŦāĻžāϰāĻž āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇ 1.0.0
  3. āφāĻĒāĻĄā§‡āϟāϟāĻŋ āϏāĻĢāϞ āĻšāϝāĻŧ⧇āϛ⧇ āĻāĻŦāĻ‚ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋāϰ āĻāĻ•āĻžāϧāĻŋāĻ• āϚāϞāĻŽāĻžāύ āωāĻĻāĻžāĻšāϰāĻŖ āϰāϝāĻŧ⧇āϛ⧇ 1.0.0 āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ 2.0.0. āĻĒā§āϰāĻ¤ā§āϝ⧇āϕ⧇āχ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇āϰ āϏāĻžāĻĨ⧇ āϝ⧋āĻ—āĻžāϝ⧋āĻ— āĻ•āϰ⧇ v2
  4. āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ 1.0.0 āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇ āωāĻĒāĻžāϧāĻŋ āĻ•āϞāĻžāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āύāĻž, āĻ•āĻŋāĻ¨ā§āϤ⧁ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ 2.0.0 āĻŦā§āϝāĻŦāĻšāĻžāϰāϏāĻŽā§‚āĻš. āϤāĻžāϰāĻž āĻāϕ⧇ āĻ…āĻĒāϰ⧇āϰ āϏāĻžāĻĨ⧇ āĻšāĻ¸ā§āϤāĻ•ā§āώ⧇āĻĒ āĻ•āϰ⧇ āύāĻž, āĻāĻŦāĻ‚ āϕ⧋āύ āĻ¤ā§āϰ⧁āϟāĻŋ āĻĨāĻžāĻ•āĻž āωāϚāĻŋāϤ āύāϝāĻŧāĨ¤
  5. āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ 2.0.0 āĻĒāĻļā§āϚāĻžāĻĻāĻ—āĻžāĻŽā§€ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧇ āĻĒ⧁āϰāĻžāύ⧋ āĻāĻŦāĻ‚ āύāϤ⧁āύ āωāĻ­āϝāĻŧ āĻ•āϞāĻžāĻŽā§‡ āĻĄā§‡āϟāĻž āϏāĻžā§āϚāϝāĻŧ āĻ•āϰ⧇

āĻāϟāĻž āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖāĨ¤ āφāĻĒāύāĻžāϰ āϝāĻĻāĻŋ āϕ⧋āύāĻ“ āĻĒā§āϰāĻļā§āύ āĻĨāĻžāϕ⧇ āϝāĻž āĻĒ⧁āϰāĻžāύ⧋/āύāϤ⧁āύ āĻ•āϞāĻžāĻŽā§‡āϰ āĻŽāĻžāύāϗ⧁āϞāĻŋāϰ āωāĻĒāϰ āĻ­āĻŋāĻ¤ā§āϤāĻŋ āĻ•āϰ⧇ āφāχāĻŸā§‡āĻŽāϗ⧁āϞāĻŋ āĻ—āĻŖāύāĻž āĻ•āϰ⧇, āφāĻĒāύāĻžāϰ āĻŽāύ⧇ āϰāĻžāĻ–āĻž āωāϚāĻŋāϤ āϝ⧇ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ āĻāĻ–āύ āĻĄā§āĻĒā§āϞāĻŋāϕ⧇āϟ āĻŽāĻžāύ āϰāϝāĻŧ⧇āϛ⧇ (āϏāĻŽā§āĻ­āĻŦāϤ āϤāĻžāϰāĻž āĻāĻ–āύāĻ“ āĻ¸ā§āĻĨāĻžāύāĻžāĻ¨ā§āϤāϰ āĻ•āϰāϛ⧇)āĨ¤ āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āϏāĻ‚āĻ–ā§āϝāĻž āĻ—āĻŖāύāĻž āĻ•āϰāϤ⧇ āϚāĻžāύ āϝāĻžāĻĻ⧇āϰ āĻļ⧇āώ āύāĻžāĻŽ (āĻ•āϞāĻžāĻŽāϟāĻŋ āϝāĻžāχ āĻŦāϞāĻž āĻšā§‹āĻ• āύāĻž āϕ⧇āύ) āĻ…āĻ•ā§āώāϰ āĻĻāĻŋāϝāĻŧ⧇ āĻļ⧁āϰ⧁ āĻšāϝāĻŧ⧇āϛ⧇ A, āϤāĻžāϰāĻĒāϰ āĻĄā§‡āϟāĻž āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āύāĻž āĻšāĻ“āϝāĻŧāĻž āĻĒāĻ°ā§āϝāĻ¨ā§āϤ (old → new āĻ•āϞāĻžāĻŽ) āϝāĻĻāĻŋ āφāĻĒāύāĻŋ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āĻ•āϞāĻžāĻŽ āĻ…āύ⧁āϏāĻ¨ā§āϧāĻžāύ āĻ•āϰ⧇āύ āϤāĻŦ⧇ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ āĻ…āϏāĻ™ā§āĻ—āϤ āĻĄā§‡āϟāĻž āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤

āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϰ⧋āϞāĻŦā§āϝāĻžāĻ•

āĻāĻ–āύ āφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϛ⧇ āĻ…ā§āϝāĻžāĻĒ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āϰāϝāĻŧ⧇āϛ⧇ 2.0.0 āĻāĻŦāĻ‚ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āχāύ v2.

āϧāĻžāĻĒ:

  1. āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϰ⧋āϞ āĻŦā§āϝāĻžāĻ• 1.0.0.
  2. āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ 1.0.0 āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇ āĻāĻ•āϟāĻŋ āĻ•āϞāĻžāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āύāĻž surname, āϤāĻžāχ āϰ⧋āϞāĻŦā§āϝāĻžāĻ• āϏāĻĢāϞ āĻšāĻ“āϝāĻŧāĻž āωāϚāĻŋāϤ

āĻĄāĻŋāĻŦāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āύāĻžāĻŽā§‡āϰ āĻāĻ•āϟāĻŋ āĻ•āϞāĻžāĻŽ āϰāϝāĻŧ⧇āϛ⧇ last_name.

āĻĢā§āϞāĻžāχāĻ“āϝāĻŧ⧇ āϏ⧋āĻ°ā§āϏ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ:

CREATE TABLE PERSON (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY,
    first_name varchar(255) not null,
    last_name varchar(255) not null
);

insert into PERSON (first_name, last_name) values ('Dave', 'Syer');

āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āϝ⧋āĻ— āĻ•āϰ⧁āύ surname.

āĻŽāύ⧋āϝ⧋āĻ—. āĻŽāύ⧇ āϰāĻžāĻ–āĻŦ⧇āύ āφāĻĒāύāĻŋ āϝ⧇ āĻ•āϞāĻžāĻŽāϟāĻŋ āϝ⧋āĻ— āĻ•āϰāϛ⧇āύ āϤāĻžāϤ⧇ āϕ⧋āύ⧋ NOT NULL āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž āϝ⧋āĻ— āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύ āύāĻžāĨ¤ āφāĻĒāύāĻŋ JAR āϰ⧋āϞāĻŦā§āϝāĻžāĻ• āĻ•āϰāϞ⧇, āĻĒ⧁āϰāĻžāύ⧋ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ āϝ⧋āĻ— āĻ•āϰāĻž āĻ•āϞāĻžāĻŽ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āϕ⧋āύ āϧāĻžāϰāĻŖāĻž āĻĨāĻžāĻ•āĻŦ⧇ āύāĻž āĻāĻŦāĻ‚ āĻāϟāĻŋ āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧāĻ­āĻžāĻŦ⧇ NULL āĻ āϏ⧇āϟ āĻ•āϰāĻŦ⧇āĨ¤ āϝāĻĻāĻŋ āĻāĻŽāύ āĻāĻ•āϟāĻŋ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž āĻĨāĻžāϕ⧇ āϤāĻŦ⧇ āĻĒ⧁āϰāĻžāύ⧋ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύāϟāĻŋ āϕ⧇āĻŦāϞ āϭ⧇āϙ⧇ āϝāĻžāĻŦ⧇āĨ¤

-- NOTE: This field can't have the NOT NULL constraint cause if you rollback, the old version won't know about this field
-- and will always set it to NULL
ALTER TABLE PERSON ADD surname varchar(255);

-- WE'RE ASSUMING THAT IT'S A FAST MIGRATION - OTHERWISE WE WOULD HAVE TO MIGRATE IN BATCHES
UPDATE PERSON SET PERSON.surname = PERSON.last_name

āϕ⧋āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

āφāĻŽāϰāĻž āĻĄā§‡āϟāĻž āĻšāĻŋāϏāĻžāĻŦ⧇ āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰāĻŋ last_name, āĻāĻŦāĻ‚ āχāύ surname. āĻāĻ•āχ āϏāĻŽāϝāĻŧ⧇ āĻĨ⧇āϕ⧇ āφāĻŽāϰāĻž āĻĒāĻĄāĻŧāĻŋ last_name, āϝ⧇āĻšā§‡āϤ⧁ āĻāχ āĻ•āϞāĻžāĻŽāϟāĻŋ āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āĻĒā§āϰāĻžāϏāĻ™ā§āĻ—āĻŋāĻ•āĨ¤ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻž āϚāϞāĻžāĻ•āĻžāϞ⧀āύ, āĻ•āĻŋāϛ⧁ āĻ…āύ⧁āϰ⧋āϧ āĻāĻ•āϟāĻŋ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āωāĻĻāĻžāĻšāϰāĻŖ āĻĻā§āĻŦāĻžāϰāĻž āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻ•āϰāĻž āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āϝāĻž āĻāĻ–āύāĻ“ āφāĻĒāĻĄā§‡āϟ āĻ•āϰāĻž āĻšāϝāĻŧāύāĻŋāĨ¤

/*
 * Copyright 2012-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sample.flyway;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private String firstName;
    private String lastName;
    private String surname;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /**
     * Reading from the new column if it's set. If not the from the old one.
     *
     * When migrating from version 1.0.0 -> 2.0.0 this can lead to a possibility that some data in
     * the surname column is not up to date (during the migration process lastName could have been updated).
     * In this case one can run yet another migration script after all applications have been deployed in the
     * new version to ensure that the surname field is updated.
     *
     * However it makes sense since when looking at the migration from 2.0.0 -> 3.0.0. In 3.0.0 we no longer
     * have a notion of lastName at all - so we don't update that column. If we rollback from 3.0.0 -> 2.0.0 if we
     * would be reading from lastName, then we would have very old data (since not a single datum was inserted
     * to lastName in version 3.0.0).
     */
    public String getSurname() {
        return this.surname != null ? this.surname : this.lastName;
    }

    /**
     * Storing both FIRST_NAME and SURNAME entries
     */
    public void setSurname(String surname) {
        this.lastName = surname;
        this.surname = surname;
    }

    @Override
    public String toString() {
        return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName + ", surname=" + this.surname
                + "]";
    }
}

āϧāĻžāĻĒ 3: āϕ⧋āĻĄ āĻĨ⧇āϕ⧇ āĻļ⧇āώ_āύāĻžāĻŽ āϏāϰāĻžāύ⧋ āĻšāĻšā§āϛ⧇

āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ: 3.0.0

āĻĄāĻŋāĻŦāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ:v3

āĻŽāĻ¨ā§āϤāĻŦā§āϝ

āĻŦāĻŋāσāĻĻā§āϰāσ āĻĒā§āϰāϤāĻŋ.: āĻ¸ā§āĻĒāĻˇā§āϟāϤāχ, āĻŽā§‚āϞ āύāĻŋāĻŦāĻ¨ā§āϧ⧇ āϞ⧇āĻ–āĻ• āϭ⧁āϞāĻŦāĻļāϤ āĻāχ āĻŦā§āϞāϕ⧇āϰ āĻŸā§‡āĻ•ā§āϏāϟāϟāĻŋ āϧāĻžāĻĒ 2 āĻĨ⧇āϕ⧇ āĻ…āύ⧁āϞāĻŋāĻĒāĻŋ āĻ•āϰ⧇āϛ⧇āύāĨ¤ āĻāχ āϧāĻžāĻĒ⧇, āĻ•āϞāĻžāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāĻŽāύ āĻ•āĻžāĻ°ā§āϝāĻ•āĻžāϰāĻŋāϤāĻž āĻ…āĻĒāϏāĻžāϰāϪ⧇āϰ āϞāĻ•ā§āĻˇā§āϝ⧇ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϕ⧋āĻĄā§‡ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž āωāϚāĻŋāϤāĨ¤ last_name.

āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āĻ•āϞāĻžāĻŽ āϝ⧋āĻ— āĻ•āϰ⧇ āĻāĻŦāĻ‚ āĻāϰ āĻŦāĻŋāώāϝāĻŧāĻŦāĻ¸ā§āϤ⧁ āĻ…āύ⧁āϞāĻŋāĻĒāĻŋ āĻ•āϰ⧇, āφāĻŽāϰāĻž āĻĒāĻŋāĻ›āύ⧇āϰ āĻĻāĻŋāϕ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āϤ⧈āϰāĻŋ āĻ•āϰ⧇āĻ›āĻŋāĨ¤ āĻāĻ›āĻžāĻĄāĻŧāĻžāĻ“, āϝāĻĻāĻŋ āφāĻŽāϰāĻž JAR āϰ⧋āϞāĻŦā§āϝāĻžāĻ• āĻ•āϰāĻŋ āĻŦāĻž āĻāĻ•āϟāĻŋ āĻĒ⧁āϰāĻžāύ⧋ JAR āϚāϞāĻŽāĻžāύ āĻĨāĻžāϕ⧇ āϤāĻŦ⧇ āĻāϟāĻŋ āĻ•āĻžāĻ°ā§āϝāĻ•āϰ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āϭ⧇āϙ⧇ āϝāĻžāĻŦ⧇ āύāĻžāĨ¤

āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϰ⧋āϞāĻŦā§āϝāĻžāĻ•

āĻŦāĻ°ā§āϤāĻŽāĻžāύ⧇ āφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϛ⧇ āĻ…ā§āϝāĻžāĻĒ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āϰāϝāĻŧ⧇āϛ⧇ 3.0.0 āĻāĻŦāĻ‚ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ v3. āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ 3.0.0 āĻĄā§‡āϟāĻž āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰ⧇ āύāĻž last_name. āĻāϰ āĻŽāĻžāύ⧇ āĻšāϞ āϝ⧇ surname āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āφāĻĒ āϟ⧁ āĻĄā§‡āϟ āϤāĻĨā§āϝ āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰāĻž āĻšāϝāĻŧ.

āϧāĻžāĻĒ:

  1. āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ āφāĻĒāύāĻžāϰ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϰ⧋āϞ āĻŦā§āϝāĻžāĻ• 2.0.0.
  2. āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ 2.0.0 āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāĻŦāĻ‚ last_name и surname.
  3. āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ 2.0.0 āĻ—ā§āϰāĻšāύ āĻ•āϰāĻŦ⧇ surname, āϝāĻĻāĻŋ āĻāϟāĻŋ āĻļā§‚āĻ¨ā§āϝ āύāĻž āĻšāϝāĻŧ, āĻ…āĻ¨ā§āϝāĻĨāĻžāϝāĻŧ -last_name

āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇ āϕ⧋āύ āĻ•āĻžāĻ āĻžāĻŽā§‹āĻ—āϤ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āύ⧇āχāĨ¤ āĻĒ⧁āϰāĻžāύ⧋ āĻĄā§‡āϟāĻžāϰ āĻšā§‚āĻĄāĻŧāĻžāĻ¨ā§āϤ āĻ¸ā§āĻĨāĻžāύāĻžāĻ¨ā§āϤāϰ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āύāĻŋāĻŽā§āύāϞāĻŋāĻ–āĻŋāϤ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟāϟāĻŋ āĻ•āĻžāĻ°ā§āϝāĻ•āϰ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇:

-- WE'RE ASSUMING THAT IT'S A FAST MIGRATION - OTHERWISE WE WOULD HAVE TO MIGRATE IN BATCHES
-- ALSO WE'RE NOT CHECKING IF WE'RE NOT OVERRIDING EXISTING ENTRIES. WE WOULD HAVE TO COMPARE
-- ENTRY VERSIONS TO ENSURE THAT IF THERE IS ALREADY AN ENTRY WITH A HIGHER VERSION NUMBER
-- WE WILL NOT OVERRIDE IT.
UPDATE PERSON SET PERSON.surname = PERSON.last_name;

-- DROPPING THE NOT NULL CONSTRAINT; OTHERWISE YOU WILL TRY TO INSERT NULL VALUE OF THE LAST_NAME
-- WITH A NOT_NULL CONSTRAINT.
ALTER TABLE PERSON MODIFY COLUMN last_name varchar(255) NULL DEFAULT NULL;

āϕ⧋āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

āĻŦāĻŋāσāĻĻā§āϰāσ āĻĒā§āϰāϤāĻŋāĨ¤: āĻāχ āĻŦā§āϞāϕ⧇āϰ āĻŦāĻ°ā§āĻŖāύāĻžāϟāĻŋāĻ“ āϞ⧇āĻ–āĻ• āϭ⧁āϞāĻŦāĻļāϤ ⧍āϝāĻŧ āϧāĻžāĻĒ āĻĨ⧇āϕ⧇ āĻ…āύ⧁āϞāĻŋāĻĒāĻŋ āĻ•āϰ⧇āϛ⧇āύāĨ¤ āύāĻŋāĻŦāĻ¨ā§āϧ⧇āϰ āϝ⧁āĻ•ā§āϤāĻŋ āĻ…āύ⧁āϏāĻžāϰ⧇, āĻāχ āϧāĻžāĻĒ⧇ āϕ⧋āĻĄā§‡ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ⧇āϰ āϞāĻ•ā§āĻˇā§āϝ āĻšāĻ“āϝāĻŧāĻž āωāϚāĻŋāϤ āĻ•āϞāĻžāĻŽā§‡āϰ āϏāĻžāĻĨ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇ āĻāĻŽāύ āωāĻĒāĻžāĻĻāĻžāύāϗ⧁āϞāĻŋāϕ⧇ āϏāϰāĻŋāϝāĻŧ⧇ āĻĢ⧇āϞāĻžāĨ¤ last_name.

āφāĻŽāϰāĻž āĻĄā§‡āϟāĻž āĻšāĻŋāϏāĻžāĻŦ⧇ āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰāĻŋ last_name, āĻāĻŦāĻ‚ āχāύ surname. āωāĻĒāϰāĻ¨ā§āϤ⧁, āφāĻŽāϰāĻž āĻ•āϞāĻžāĻŽ āĻĨ⧇āϕ⧇ āĻĒāĻĄāĻŧāĻž last_name, āϝ⧇āĻšā§‡āϤ⧁ āĻāϟāĻŋ āϏāĻŦāĻšā§‡āϝāĻŧ⧇ āĻĒā§āϰāĻžāϏāĻ™ā§āĻ—āĻŋāĻ•āĨ¤ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻž āϚāϞāĻžāĻ•āĻžāϞ⧀āύ, āĻ•āĻŋāϛ⧁ āĻ…āύ⧁āϰ⧋āϧ āĻāĻŽāύ āĻāĻ•āϟāĻŋ āωāĻĻāĻžāĻšāϰāĻŖ āĻĻā§āĻŦāĻžāϰāĻž āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻ•āϰāĻž āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āϝāĻž āĻāĻ–āύāĻ“ āφāĻĒāĻ—ā§āϰ⧇āĻĄ āĻ•āϰāĻž āĻšāϝāĻŧāύāĻŋāĨ¤

/*
 * Copyright 2012-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sample.flyway;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    private String firstName;
    private String surname;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getSurname() {
        return this.surname;
    }

    public void setSurname(String lastname) {
        this.surname = lastname;
    }

    @Override
    public String toString() {
        return "Person [firstName=" + this.firstName + ", surname=" + this.surname
                + "]";
    }
}

āϧāĻžāĻĒ 4: āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĨ⧇āϕ⧇ āĻļ⧇āώ_āύāĻžāĻŽ āϏāϰāĻžāύ⧋ āĻšāĻšā§āϛ⧇

āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ: 4.0.0

āĻĄāĻŋāĻŦāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ: v4

āĻŽāĻ¨ā§āϤāĻŦā§āϝ

āϝ⧇ āĻ•āĻžāϰāϪ⧇ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āϕ⧋āĻĄ 3.0.0 āĻ•āϞāĻžāĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āύāĻŋ last_name, āĻŽā§ƒāĻ¤ā§āϝ⧁āĻĻāĻ¨ā§āĻĄā§‡āϰ āϏāĻŽāϝāĻŧ āĻ–āĻžāϰāĻžāĻĒ āĻ•āĻŋāϛ⧁ āϘāϟāĻŦ⧇ āύāĻž āϝāĻĻāĻŋ āφāĻŽāϰāĻž āĻĢāĻŋāϰ⧇ āϝāĻžāχ 3.0.0 āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻĨ⧇āϕ⧇ āĻāĻ•āϟāĻŋ āĻ•āϞāĻžāĻŽ āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻžāϰ āĻĒāϰ⧇āĨ¤

āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻāĻ•ā§āϏāĻŋāĻ•āĻŋāωāĻļāύ āϞāĻ—

We will do it in the following way:

01) Run 1.0.0
02) Wait for the app (1.0.0) to boot
03) Generate a person by calling POST localhost:9991/person to version 1.0.0
04) Run 2.0.0
05) Wait for the app (2.0.0) to boot
06) Generate a person by calling POST localhost:9991/person to version 1.0.0
07) Generate a person by calling POST localhost:9992/person to version 2.0.0
08) Kill app (1.0.0)
09) Run 3.0.0
10) Wait for the app (3.0.0) to boot
11) Generate a person by calling POST localhost:9992/person to version 2.0.0
12) Generate a person by calling POST localhost:9993/person to version 3.0.0
13) Kill app (3.0.0)
14) Run 4.0.0
15) Wait for the app (4.0.0) to boot
16) Generate a person by calling POST localhost:9993/person to version 3.0.0
17) Generate a person by calling POST localhost:9994/person to version 4.0.0

Starting app in version 1.0.0
Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

{"firstName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2","lastName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2"}

Starting app in version 2.0.0

Generate a person in version 1.0.0
Sending a post to 127.0.0.1:9991/person. This is the response:

{"firstName":"e41ee756-4fa7-4737-b832-e28827a00deb","lastName":"e41ee756-4fa7-4737-b832-e28827a00deb"}

Generate a person in version 2.0.0
Sending a post to 127.0.0.1:9992/person. This is the response:

{"firstName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","lastName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","surname":"0c1240f5-649a-4bc5-8aa9-cff855f3927f"}

Killing app 1.0.0

Starting app in version 3.0.0

Generate a person in version 2.0.0
Sending a post to 127.0.0.1:9992/person. This is the response:
{"firstName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","lastName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","surname":"74d84a9e-5f44-43b8-907c-148c6d26a71b"}

Generate a person in version 3.0.0
Sending a post to 127.0.0.1:9993/person. This is the response:
{"firstName":"c6564dbe-9ab5-40ae-9077-8ae6668d5862","surname":"c6564dbe-9ab5-40ae-9077-8ae6668d5862"}

Killing app 2.0.0

Starting app in version 4.0.0

Generate a person in version 3.0.0
Sending a post to 127.0.0.1:9993/person. This is the response:

{"firstName":"cbe942fc-832e-45e9-a838-0fae25c10a51","surname":"cbe942fc-832e-45e9-a838-0fae25c10a51"}

Generate a person in version 4.0.0
Sending a post to 127.0.0.1:9994/person. This is the response:

{"firstName":"ff6857ce-9c41-413a-863e-358e2719bf88","surname":"ff6857ce-9c41-413a-863e-358e2719bf88"}

āĻĄāĻŋāĻŦāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

āϤ⧁āϞāύāĻžāĻŽā§‚āϞāĻ•āĻ­āĻžāĻŦ⧇ v3 āφāĻŽāϰāĻž āĻļ⧁āϧ⧁ āĻ•āϞāĻžāĻŽ āĻ…āĻĒāϏāĻžāϰāĻŖ last_name āĻāĻŦāĻ‚ āĻ…āύ⧁āĻĒāĻ¸ā§āĻĨāĻŋāϤ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž āϝ⧋āĻ— āĻ•āϰ⧁āύāĨ¤

-- REMOVE THE COLUMN
ALTER TABLE PERSON DROP last_name;

-- ADD CONSTRAINTS
UPDATE PERSON SET surname='' WHERE surname IS NULL;
ALTER TABLE PERSON ALTER COLUMN surname VARCHAR NOT NULL;

āϕ⧋āĻĄ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ

āϕ⧋āĻĄā§‡ āϕ⧋āύ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āύ⧇āχāĨ¤

āωāĻĒāϏāĻ‚āĻšāĻžāϰ

āφāĻŽāϰāĻž āϏāĻĢāϞāĻ­āĻžāĻŦ⧇ āĻĒāĻŋāĻ›āύ⧇āϰ-āĻ…āϏāĻ™ā§āĻ—āϤ āĻ•āϞāĻžāĻŽā§‡āϰ āύāĻžāĻŽ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ⧇āϰ āϜāĻ¨ā§āϝ āĻŦ⧇āĻļ āĻ•āϝāĻŧ⧇āĻ•āϟāĻŋ āĻĒāĻŋāĻ›āύ⧇āϰ-āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž āϏāĻŽā§āĻĒāĻžāĻĻāύ āĻ•āϰ⧇ āĻĒā§āϰāϝāĻŧā§‹āĻ— āĻ•āϰ⧇āĻ›āĻŋāĨ¤ āύ⧀āĻšā§‡ āϏāĻŽā§āĻĒāĻžāĻĻāĻŋāϤ āĻ•ā§āϰāĻŋāϝāĻŧāĻžāϗ⧁āϞāĻŋāϰ āĻāĻ•āϟāĻŋ āϏāĻžāϰāϏāĻ‚āĻ•ā§āώ⧇āĻĒ āϰāϝāĻŧ⧇āϛ⧇:

  1. āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž 1.0.0 ҁ v1 āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻ¸ā§āĻ•āĻŋāĻŽāĻž (āĻ•āϞāĻžāĻŽā§‡āϰ āύāĻžāĻŽ = last_name)
  2. āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž 2.0.0, āϝāĻž āϤāĻĨā§āϝ āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰ⧇ last_name и surname. āφāĻŦ⧇āĻĻāύ āĻĨ⧇āϕ⧇ āĻĒāĻĄāĻŧāĻž last_name. āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ āφāϛ⧇ v2āĻŽāϤ āĻ•āϞāĻžāĻŽ āϧāĻžāϰāĻŖāĻ•āĻžāϰ⧀ last_name, āĻāĻŦāĻ‚ surname. surname l āĻāϰ āĻāĻ•āϟāĻŋ āĻ…āύ⧁āϞāĻŋāĻĒāĻŋast_name. (āĻĻā§āϰāĻˇā§āϟāĻŦā§āϝ: āĻāχ āĻ•āϞāĻžāĻŽā§‡ āĻ…āĻŦāĻļā§āϝāχ āύāĻžāϞ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž āĻĨāĻžāĻ•āĻŦ⧇ āύāĻž)
  3. āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž 3.0.0, āϝāĻž āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻĄā§‡āϟāĻž āϏāĻžā§āϚāϝāĻŧ āĻ•āϰ⧇ surname āĻāĻŦāĻ‚ āωāĻĒāĻžāϧāĻŋ āĻĨ⧇āϕ⧇ āĻĒāĻĄāĻŧ⧇āĨ¤ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇āϰ āϜāĻ¨ā§āϝ, āĻļ⧇āώ āĻŽāĻžāχāĻ—ā§āϰ⧇āĻļāύ āĻšāĻšā§āϛ⧇ last_name в surname. āĻāĻ›āĻžāĻĄāĻŧāĻžāĻ“ āĻāĻ•āϟāĻŋ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž āύāĻžāϞ āύāĻž āĻĨ⧇āϕ⧇ āϏāϰāĻžāύ⧋ āĻšāϝāĻŧ⧇āϛ⧇ last_name. āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻāĻ–āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ āφāϛ⧇ v3
  4. āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž 4.0.0 - āϕ⧋āĻĄā§‡ āϕ⧋āύ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻž āĻšāϝāĻŧ āύāĻžāĨ¤ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž v4, āϝāĻž āĻ…āĻĒāϏāĻžāϰāĻŖ āĻ•āϰ⧇ last_name. āĻāĻ–āĻžāύ⧇ āφāĻĒāύāĻŋ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇ āϕ⧋āύ⧋ āĻ…āύ⧁āĻĒāĻ¸ā§āĻĨāĻŋāϤ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž āϝ⧋āĻ— āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤

āĻāχ āĻĒāĻĻā§āϧāϤāĻŋ āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰ⧇, āφāĻĒāύāĻŋ āϏāĻŦāϏāĻŽāϝāĻŧ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ/āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ āύāĻž āϭ⧇āϙ⧇ āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻĢāĻŋāϰāĻŋāϝāĻŧ⧇ āφāύāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤

āϕ⧋āĻĄ

āĻāχ āύāĻŋāĻŦāĻ¨ā§āϧ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āϏāĻŽāĻ¸ā§āϤ āϕ⧋āĻĄ āĻāĻ–āĻžāύ⧇ āωāĻĒāϞāĻŦā§āϧ āĻ—āĻŋāϟāĻšāĻžāĻŦ. āύ⧀āĻšā§‡ āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āĻŦāĻŋāĻŦāϰāĻŖ āφāϛ⧇.

āĻĒā§āϰāĻ•āĻ˛ā§āĻĒ

āϏāĻ‚āĻ—ā§āϰāĻšāĻ¸ā§āĻĨāϞ āĻ•ā§āϞ⧋āύ āĻ•āϰāĻžāϰ āĻĒāϰ⧇, āφāĻĒāύāĻŋ āύāĻŋāĻŽā§āύāϞāĻŋāĻ–āĻŋāϤ āĻĢā§‹āĻ˛ā§āĻĄāĻžāϰ āĻ•āĻžāĻ āĻžāĻŽā§‹ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ⧇āύāĨ¤

├── boot-flyway-v1              - 1.0.0 version of the app with v1 of the schema
├── boot-flyway-v2              - 2.0.0 version of the app with v2 of the schema (backward-compatible - app can be rolled back)
├── boot-flyway-v2-bad          - 2.0.0.BAD version of the app with v2bad of the schema (backward-incompatible - app cannot be rolled back)
├── boot-flyway-v3              - 3.0.0 version of the app with v3 of the schema (app can be rolled back)
└── boot-flyway-v4              - 4.0.0 version of the app with v4 of the schema (app can be rolled back)

āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ

āφāĻĒāύāĻŋ āύ⧀āĻšā§‡āϰ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟāϗ⧁āϞāĻŋāϤ⧇ āĻŦāĻ°ā§āĻŖāĻŋāϤ āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟāϗ⧁āϞāĻŋ āϚāĻžāϞāĻžāϤ⧇ āĻĒāĻžāϰ⧇āύ, āϝāĻž āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇āϰ āĻĒāĻŋāĻ›āύ⧇āϰ-āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āĻāĻŦāĻ‚ āĻŦ⧇āĻŽāĻžāύāĻžāύ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύāϗ⧁āϞāĻŋ āĻĒā§āϰāĻĻāĻ°ā§āĻļāύ āĻ•āϰāĻŦ⧇āĨ¤

āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻŋāĻ›āύ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āϏāĻ™ā§āϗ⧇ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇, āϚāĻžāϞāĻžāύ:

./scripts/scenario_backward_compatible.sh

āĻāĻŦāĻ‚ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻŋāĻ›āύ⧇āϰ āĻŦ⧇āĻŽāĻžāύāĻžāύ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āϏāĻ™ā§āϗ⧇ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇, āϚāĻžāϞāĻžāύ:

./scripts/scenario_backward_incompatible.sh

āĻ¸ā§āĻĒā§āϰāĻŋāĻ‚ āĻŦ⧁āϟ āύāĻŽā§āύāĻž āĻĢā§āϞāĻžāχāĻ“āϝāĻŧ⧇

āϏāĻŦ āωāĻĻāĻžāĻšāϰāĻŖ āĻĨ⧇āϕ⧇ āύ⧇āĻ“āϝāĻŧāĻž āĻšāϝāĻŧ⧇āϛ⧇ Spring Boot Sample Flyway.

āφāĻĒāύāĻŋ āĻāĻ•āĻŦāĻžāϰ āĻĻ⧇āϖ⧇ āύāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āύ http://localhost:8080/flyway, āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ āĻāĻ•āϟāĻŋ āϤāĻžāϞāĻŋāĻ•āĻž āφāϛ⧇.

āĻāχ āωāĻĻāĻžāĻšāϰāϪ⧇ H2 āĻ•āύāϏ⧋āϞāĻ“ āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ āϰāϝāĻŧ⧇āϛ⧇ (āĻ http://localhost:8080/h2-console) āϝāĻžāϤ⧇ āφāĻĒāύāĻŋ āĻĄāĻžāϟāĻžāĻŦ⧇āϏ⧇āϰ āĻ¸ā§āĻĨāĻŋāϤāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāϰ⧇āύ (āĻĄāĻŋāĻĢāĻ˛ā§āϟ jdbc URL āĻšāϞ jdbc:h2:mem:testdb).

āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ

āĻāĻ›āĻžāĻĄāĻŧāĻžāĻ“ āφāĻŽāĻžāĻĻ⧇āϰ āĻŦā§āϞāϗ⧇ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āύāĻŋāĻŦāĻ¨ā§āϧ āĻĒāĻĄāĻŧ⧁āύ:

āωāĻ¤ā§āϏ: www.habr.com

DDoS āϏ⧁āϰāĻ•ā§āώāĻž, VPS VDS āϏāĻžāĻ°ā§āĻ­āĻžāϰ āϏāĻš āϏāĻžāχāϟāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āύāĻŋāĻ°ā§āĻ­āϰāϝ⧋āĻ—ā§āϝ āĻšā§‹āĻ¸ā§āϟāĻŋāĻ‚ āĻ•āĻŋāύ⧁āύ đŸ”Ĩ DDoS āϏ⧁āϰāĻ•ā§āώāĻž āϏāĻš āύāĻŋāĻ°ā§āĻ­āϰāϝ⧋āĻ—ā§āϝ āĻ“āϝāĻŧ⧇āĻŦāϏāĻžāχāϟ āĻšā§‹āĻ¸ā§āϟāĻŋāĻ‚ āĻ•āĻŋāύ⧁āύ, VPS VDS āϏāĻžāĻ°ā§āĻ­āĻžāϰ | ProHoster