Created
July 9, 2020 23:42
-
-
Save drhuffman12/75004ed6a3914f8e46319c9f6cd8c3f1 to your computer and use it in GitHub Desktop.
Ruby/SQL code to generate new unique incremented keys (e.g. usernames)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# example app code should guarantee a unique, sequenced username: | |
def calc_prefix(user, fmaxi = 7, lmaxi = 0) | |
# e.g.: extract users's first and last name (or use the email example or etc) | |
first_name = user.first_name | |
last_name = user.last_name | |
# now, force to lowercase and only (ascii? unicode?) letters and numbers | |
# first_name = first_name.downcase.gsub(/[^0-9a-z ]/i, '') # for ascii only | |
first_name = first_name.downcase.gsub(/[^\p{Alnum} -]/, '') # for unicode also | |
# last_name = last_name.downcase.gsub(/[^0-9a-z ]/i, '') # for ascii only | |
last_name = last_name.downcase.gsub(/[^\p{Alnum} -]/, '') # for unicode also | |
# and return like 'first.l' ... | |
# NOTE: We will limit to [0..fmaxi] chars for first name and likewise for last name | |
return "#{first_name[0..(fmaxi)]}.#{last_name[0..(lmaxi)]} # e.g.: "john.s" | |
end | |
def highest_count_match_with_or_with_count_suffix(prefix) | |
prefix_safer_sql = prefix.gsub('.','\.') # just a '.' means any char, so we must prefix with '\' | |
usernames = User.where("username REGEXP /^#{prefix_safer_sql}((\.[0-9]+))*$/gm").pluck(:username) #=> ["john.s", "john.s.0", "john.s.1", "john.s.2", "john.s.3", "john.s.4", "john.s.45", "john.s.456", "john.s.476865"] | |
numbers = usernames.map{|un| (un.split('.')[2] || '').to_i} #=> [0, 0, 1, 2, 3, 4, 45, 456, 476865] | |
numbers.max | |
end | |
def new_username(user, fmaxi = 7, lmaxi = 0) | |
prefix = calc_prefix(user, fmaxi, lmaxi) | |
highest_count = highest_count_match_with_or_with_count_suffix(prefix) | |
"#{prefix}.#{highest_count + 1} | |
end | |
# ... | |
username = new_username(user, fmaxi, lmaxi) | |
# test variables for the first-name-last-initial prefix matcher would be something like: | |
all_usernames = %w[ | |
johnAs | |
john.s | |
john.s.0 | |
john.s.1 | |
john.s.2 | |
john.s.3 | |
john.s.4 | |
john.s.45 | |
john.s.456 | |
john.s.476865 | |
abcjohn.s.4 | |
abcjohn.s.4xyz | |
] | |
expected_matches = %w[ | |
john.s | |
john.s.0 | |
john.s.1 | |
john.s.2 | |
john.s.3 | |
john.s.4 | |
john.s.45 | |
john.s.456 | |
john.s.476865 | |
] | |
expected_last_count = 476865 | |
expected_next_count = 476866 | |
expected_username = "john.s.476866" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment