Kotlin : How to use Kotlin Room to generate a unique id - kotlin

in my application ,apart from the primarykey of a user ,I will still need to generate a unique ID(12 -15 charactors) for showing to the public .
I am new with Room ,Could you please take a look my code ?
Thank you so much in advance !
#Entity
data class UserInfo(
#PrimaryKey(autoGenerate = true)
val userId:Int = 0,
val image: String,
val imageSource : String,//Local or Online
val username : String,
val gender :String,
val userPublicId:String, //this is the id that need to generate 12-15
val birthday : String,
val userIntro :String,
)

As mentioned #Tenfour04 you can use some ways to generate random string. I think org.apache.commons.lang3.RandomStringUtils is a good choice. For exmaple look at the following methods: randomAscii, randomAlphabetic, randomAlphanumeric.

Related

How to add data to Map copying existing values based on List of identifiers

Sorry for the poor title but it is rather hard to describe my use case in a short sentence.
Context
I have the following model:
typealias Identifier = String
data class Data(val identifier: Identifier,
val data1: String,
val data2: String)
And I have three main data structures in my use case:
A Set of Identifiers that exist and are valid in a given context. Example:
val existentIdentifiers = setOf("A-1", "A-2", "B-1", "B-2", "C-1")
A Map that contains a List of Data objects per Identifier. Example:
val dataPerIdentifier: Map<Identifier, List<Data>> = mapOf(
"A-1" to listOf(Data("A-1", "Data-1-A", "Data-2-A"), Data("A-1", "Data-1-A", "Data-2-A")),
"B-1" to listOf(Data("B-1", "Data-1-B", "Data-2-B")),
"C-1" to listOf(Data("C-1", "Data-1-C", "Data-2-C"))
)
A List of Lists that group together the Identifiers that should share the same List<Data> (each List includes always 2 Identifiers). Example
val identifiersWithSameData = listOf(listOf("A-1", "A-2"), listOf("B-1", "B-2"))
Problem / Use Case
The problem that I am trying to tackle stems from the fact that dataPerIdentifier might not contain all identifiersWithSameData given that existentIdentifiers contains such missing Identifiers. I need to add those missing Identifier to dataPerIdentifier, copying the List<Data> already in there.
Example
Given the data in the Context section:
A-1=[Data(identifier=A-1, data1=Data-1-A, data2=Data-2-A),
Data(identifier=A-1, data1=Data-1-A, data2=Data-2-A)],
B-1=[Data(identifier=B-1, data1=Data-1-B, data2=Data-2-B)],
C-1=[Data(identifier=C-1, data1=Data-1-C, data2=Data-2-C)]
The desired outcome is to update dataPerIdentifier so that it includes:
A-1=[Data(identifier=A-1, data1=Data-1-A, data2=Data-2-A),
Data(identifier=A-1, data1=Data-1-A, data2=Data-2-A)],
B-1=[Data(identifier=B-1, data1=Data-1-B, data2=Data-2-B)],
C-1=[Data(identifier=C-1, data1=Data-1-C, data2=Data-2-C)],
A-2=[Data(identifier=A-2, data1=Data-1-A, data2=Data-2-A),
Data(identifier=A-2, data1=Data-1-A, data2=Data-2-A)]
The reason is that existentIdentifiers contains A-2 that is missing in the initial dataPerIdentifier Map. B-2 is also missing in the initial dataPerIdentifier Map but existentIdentifiers does not contain it, so it is ignored.
Possible solution
I have already a working code (handleDataForMultipleIdentifiers() method is the one doing the heavy lifting), but it does not feel to be the cleanest or easiest to read:
fun main(args: Array<String>) {
val existentIdentifiers = setOf("A-1", "A-2", "B-1", "C-1")
val dataPerIdentifier: Map<Identifier, List<Data>> = mapOf(
"A-1" to listOf(Data("A-1", "Data-1-A", "Data-2-A"), Data("A-1", "Data-1-A", "Data-2-A")),
"B-1" to listOf(Data("B-1", "Data-1-B", "Data-2-B")),
"C-1" to listOf(Data("C-1", "Data-1-C", "Data-2-C"))
)
val identifiersWithSameData = listOf(listOf("A-1", "A-2"), listOf("B-1", "B-2"))
print("Original Data")
println(dataPerIdentifier)
print("Target Data")
println(dataPerIdentifier.handleDataForMultipleIdentifiers(identifiersWithSameData, existentIdentifiers))
}
fun Map<Identifier, List<Data>>.handleDataForMultipleIdentifiers(identifiersWithSameData: List<List<Identifier>>, existentIdentifiers: Set<Identifier>)
: Map<Identifier, List<Data>> {
val additionalDataPerIdentifier = identifiersWithSameData
.mapNotNull { identifiersList ->
val identifiersWithData = identifiersList.find { it in this.keys }
identifiersWithData?.let { it to identifiersList.minus(it).filter { it in existentIdentifiers } }
}.flatMap { (existentIdentifier, additionalIdentifiers) ->
val existentIdentifierData = this[existentIdentifier].orEmpty()
additionalIdentifiers.associateWith { identifier -> existentIdentifierData.map { it.copy(identifier = identifier) } }.entries
}.associate { it.key to it.value }
return this + additionalDataPerIdentifier
}
typealias Identifier = String
data class Data(val identifier: Identifier,
val data1: String,
val data2: String)
So my question is: how can I do this in a simpler way?
If identifiersWithSameData always contains 2 identifiers per item then it should not really be a list of lists, but rather a list of pairs or dedicated data classes. And if you convert this data structure into a map like this:
val identifiersWithSameData = mapOf("A-1" to "A-2", "A-2" to "A-1", "B-1" to "B-2", "B-2" to "B-1")
The the whole solution is pretty simple:
existentIdentifiers.associateWith {
dataPerIdentifier[it] ?: dataPerIdentifier[identifiersWithSameData[it]!!]!!
}
I'm not sure about both !!, for example I don't know if it is guaranteed that identifier existing in existentIdentifiers exists in identifiersWithSameData as well. You may need to tune this solution a little.

Spring data - RepositoryRestResource PUT returns 200 but does not update object

I'm using Spring's HATEOAS repo:
#RepositoryRestResource(collectionResourceRel = "equipment", path = "equipment")
interface EquipmentRepository : PagingAndSortingRepository<Equipment, Int>
Here's my domain object:
#Entity
data class Equipment(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val id: Int?,
val serialNumber: String?,
val modelNumber: String,
val make: String,
val model: String,
val year: Int,
val purchaseDate: Date,
val warrantyEnds: Date,
val cost: Double
)
I'm using cURL and Postman to create equipment and it's all good. If I use PATCH for a partial update the query updates the object - if I use the same URL and same data for PUT nothing is updated but I get a 200 response (and the old object) in postman.
How come I can PATCH http://localhost:8080/equipment/1 works but a PUT with the same data and same endpoint returns 200 but does not update the data?
No errors on the server-side on the console/logs, or any indication as to why I'm getting a 200 and no update...
I am using Kotlin, if it matters...
Try change val to var, i had the same problem and this should help.

How to group by Arraylist multidimensional

how do I group by "group" when located in the sub model?
i tried do this, but it error result
mtop.groupBy { it.sub[0].group }
this my code
// my model
data class mTop(val kategori : String, val sub : ArrayList<mSub>)
data class mSub(val id_menu : String, val nama_menu : String, val gambar : String, val group : String)
// my activity
val mtop: ArrayList<mTop> = ArrayList()
val msub: ArrayList<mSub> = ArrayList()
mtop.add(mTop(header, msub))
sorry I often ask on this forum but never helped others, because I'm a beginner and my English is bad. Thank You
mtop.groupBy { it.sub[0].group }
The error you are getting is because sub is empty and you are trying to get the first element.
What you can probably do is to do a filter before trying to groupBy:
mtop.filter{it.sub.isNotEmpty()}.groupBy{it.sub[0].group}

How to get String description/value?

In Kotlin, how to get the raw value of the String?
For example,
val value: String = "Adrian"
Expected result:
"Cannot find value: Adrian"
I am coming from Swift and I know in swift it works like this
let value: String = "Adrian"
print("Cannot find \(string.description): \(value)")
Another example in Swift,
let a: String = "b"
print("\(a.description) = \(a)"
///prints "a = b"
Im guessing a String extension is needed given I read the Kotlin String documentation and seems none of the choices provides the expected result.
A simple problem but I really can't solve it:(
This might help you. For this you have to use Kotlin reflection:
Example:
data class Person(val name:String)
fun main(){
val person = Person("Birju")
val prop = person::name
println("Property Name: ${prop.name}")
println("Property Value: ${prop.get()}")
}
How about
println("value :$value")
You don't need concatination operator(+) to concat strings in kotlin

get a list of parsed json elements

I parsed a json string to the following object structure using gson:
data class Base (
val expand: String,
val startAt: Long,
val maxResults: Long,
val total: Long,
val issues: List<Issue>
)
data class Issue (
val expand: String,
val id: String,
val self: String,
val key: String,
val fields: Fields
)
data class Fields (
val summary: String,
val issuetype: Issuetype,
val customfield10006: Long? = null,
val created: String,
val customfield11201: String? = null,
val status: Status,
val customfield10002: Customfield10002? = null,
val customfield10003: String? = null
)
Everything works fine and also the object model is correct, because I can access each element of the object.
However, I encountered the problem that I dont know how to get a list of all field-elements. Right now, I have only figured out how to access one item (by using an index and get()-function):
val baseObject = gson.fromJson(response, Base::class.java)
val fieldsList = baseObject.issues.get(0).fields
I actually want to have a list of all field elements and not just one. Is there a gson function allowing me to do that? I couldn't find anything about it in the gson documentation for java.
You don't have to look for some gson function when you've already created a baseObject. You just need to get from each issue it's fields and you can use a map function to achieve this, it will convert each issue to a new type so you can get issue fields there
val fieldFromAllIssues: List<Fields> = baseObject.issues.map { it.fields }
it in this context is a one issue. More explanation about it is here