YAML data format for mongodb collections and referenced entities - scala

I want to load test data in my scala play application from data.yml file
which is in YAML format.
My entities looks like:
#Entity("users")
User(#Required val uname: String, val isAdmin: Boolean = false) {
#Id var id: ObjectId = _
#Reference val accounts = new ArrayList[Account]
}
#Entity("account")
class Account {
#Id var id: ObjectId = _
#Embedded val addresses = new ArrayList[Address]
#Reference val departments = new ArrayList[Department]
var description : String = _
}
class Address {
street: String = _
city: String = _
}
#Entity("department")
class Department {
#Id var id: ObjectId = _
principal: String = _
}
This is what almost a blank data.yml look like:
User(foo):
uname: Foo
accounts:
I want to load one user with 2 accounts. One of the account has just one address and one department, the other account has 2 addresses and one department to keep things as simple as possible. So what the complete yml data looks to achieve this?

Why can't you just use lists with keys? Using the '- key' notation or '[key1, key2]'? Example:
Department(dep1):
..
Address(address1):
..
Address(address2):
..
Account(account1):
..
addresses:
- address1
departments:
- dep1
Account(account2):
..
addresses:
- address1
- address2
departments:
- dep1
User(user1):
..
accounts:
- account1
- account2
Check http://en.wikipedia.org/wiki/Yaml#Lists

Related

Using class and struct

class Account:
let id
let type
let balance
# Account(nat?, account_type?, num?) -> Account?
# Constructs an account with the given ID number, account type, and
# balance. The balance cannot be negative.
def __init__(self, id, type, balance):
if balance < 0: error('Account: negative balance')
if not account_type?(type): error('Account: unknown type')
self.id = id
self.type = type
self.balance = balance
struct customer:
let name
let bank_account
The above class and struct are given. My understanding is that we have to substitute the Account class in place of bank_account in struct. The purpose is to create a function that would add a new bank account information into the existing or empty array every time a function is called. I just tried it the following way and it didn't seem to work. Any suggestions or tips would be appreciated. The language I use was DSSL2. Thanks.
def open_account(name, type, customers):
let newacc = customer(name, Account(id, type, balance))
newacc.name = name
newacc.Account.type = type
newacc.Account.balance = 0
if len.customers == 0: newacc.Account.id = 1
else: newacc.Account.id = customers[len.customers-1].Account.id + 1
customers = customers + newacc
You should not substitute Account for anything; you should set the field bank_account to an instance of Account.
That's what the struct creation does for you, so you don't need to think about it.
You need to determine the id first, and the field access syntax is object.field, not field.object or object.type.field.
Also, assigning to customers only changes the value of that variable, not the value of the object it represents (DSSL does not have call-by-reference).
You need to use one of the mutating methods, such as push_back.
And the struct-creation syntax is
struct_name { field1: value1, field2: value2, field3: value3 }
So (thoroughly untested), something like this:
def open_account(name, type, customers):
if customers.empty?:
id = 1
else:
id = customers[customers.len-1].id + 1
let newcustomer = customer { name: name, bank_account: Account(id, type, 0) }
customers.push_back(newcustomer)

error: instance member 'tomato' cannot be used on type 'hamburger'

1.what I code
class hamburger {
var tomato: String
var patty: String
var bread: String
var number: Int
init(_ tomato: String, _ patty: String, _ bread: String, _ number: Int) {
self.tomato = tomato
self.patty = patty
self.bread = bread
self.number = number
}
init() {
self.tomato = "tomato"
self.patty = "patty"
self.bread = "bread"
self.number = 10
}
}
let sandwich = hamburger("texas" , "iii" , "iii" , 10)
print(hamburger.tomato)
2.error message
Playground execution failed:
error: dotinstall.playground:342:7: error: instance member 'tomato'
cannot be used on type 'hamburger'
print(hamburger.tomato)
^~~~~~~~~ ~~~~~~
3.The sample I followed
enter code here// Class
class User {
let name: String // property
var score: Int
init(name: String, score: Int) {
init(_ name: String, _ score: Int) {
self.name = name
self.score = score
}
init() {
self.name = "bob"
self.score = 30
}
}
//let tom = User(name: "tom", score: 23)
let tom = User("tom", 23)
print(tom.name)
print(tom.score)
let bob = User()
print(bob.name)
print(bob.score)
I have coded like 1 following 3, but I got a error message like 2.
what I did to solve
・anyway follow this sample to be like same
・studied a basic of class syntax, initializer, instance on website
・was looking for a mistypes
・I checked the order of property
I don't why it is not worked even if I just follow the sample code.
please give me tips on the solution.
thanks
You're making a mistake regarding object oriented programming. With hamburger.tomato you try to access the property tomato of the Class Hamburger, not the Object, which is sandwich here. So the solution would be:
print(sandwich.tomato)
In the future, what you might want to do is take a look at styling your code better. Classes(Hamburger) are written starting with an uppercased letter, while the objects, or instances(sandwich), of the Classes are written starting with a lowercased letter.

How can I properly display a much readable output using sorting?

The output of my code is all good, it is already sorted, but the problem is that, it contains some garbage value that I do not need, I will provide the example output of it.
Here is my code:
struct Student {
var id: Int = 0;
var name: String = String();
var course: String = String();
var GPA: Float = 0.0;
}
let student = [
Student(id: 201520032, name: "Ton Agnis", course: "BSITWMA", GPA: 3.69),
Student(id: 201620122, name: "Juan Cruz", course: "BSCSSE", GPA: 2.23),
Student(id: 201723214, name: "Pedro Sy", course: "BSITAGD", GPA: 2.87),
Student(id: 201418492, name: "Phot xPro", course: "BSCPE", GPA: 3.99)
]
func stud(get studs:[Student]){
print("Student No.\t\tID\t\tName\t\t\tCourse\t\tGPA")
for i in 0...studs.count - 1{
print("Student \(i+1) \t \(student[i].id)\t\(student[i].name)\t\t\(student[i].course)\t\t\(student[i].GPA)")
}
}
let x = student.sorted{ $0.GPA < $1.GPA }
stud(get: student)
print(x)
Here is the Output of the Given Code
As you can see the output displays some values that is not needed.
What I want to be displayed is a better readable sorted of values given.
Thank You!
If you make your custom classes conform to the CustomStringConvertible protocol (add a single computed variable, description, of type String) then when you print one of those objects it displays nicely formatted.
You could use the formatting of your print statement with tabs as the starting point.
The function stud is already printing your student array in a formatted way.
Remove print(x) at the end of the code you posted to get a clean output.
Edit:
Also if I understand correctly your needs, you want to print the sorted list of students by GPA. (x in your code)
You can do it by passing x to the stud function and by fixing the stud function to use the function parameter instead of student var.
struct Student {
var id: Int = 0;
var name: String = String();
var course: String = String();
var GPA: Float = 0.0;
}
let student = [
Student(id: 201520032, name: "Ton Agnis", course: "BSITWMA", GPA: 3.69),
Student(id: 201620122, name: "Juan Cruz", course: "BSCSSE", GPA: 2.23),
Student(id: 201723214, name: "Pedro Sy", course: "BSITAGD", GPA: 2.87),
Student(id: 201418492, name: "Phot xPro", course: "BSCPE", GPA: 3.99)
]
func stud(get studs:[Student]){
print("Student No.\t\tID\t\tName\t\t\tCourse\t\tGPA")
for i in 0..<studs.count {
print("Student \(i+1) \t \(studs[i].id)\t\(studs[i].name)\t\t\(studs[i].course)\t\t\(studs[i].GPA)")
}
}
let x = student.sorted{ $0.GPA < $1.GPA }
stud(get: x)

SQLite Insert is not working properly in swift

I am trying to insert data from array into my table. If the insert is done I think, its suppose to print it in the console, but it is not. So I tried db.trace(println) and it shows me
SELECT * FROM "formatedData1"
My createDatabase function:
func createDatabase(){
var data = db["formatedData1"]
db.create(table: data, ifNotExists: true){ d in
d.column(type, primaryKey: true)
d.column(ada)
d.column(code)
d.column(name)
d.column(proof)
d.column(size)
d.column(case_size)
d.column(price)
}
for var i = 0; i < self.dataArrayMut.count; ++i{
data.insert(type <- (self.dataArrayMut[i].valueForKey("Type") as! String), ada <- (self.dataArrayMut[i].valueForKey("ADA") as! String), code <- (self.dataArrayMut[i].valueForKey("Code") as! String), name <- (self.dataArrayMut[i].valueForKey("Name") as! String), proof <- (self.dataArrayMut[i].valueForKey("Proof") as! String), size <- (self.dataArrayMut[i].valueForKey("Size") as! String), case_size <- (self.dataArrayMut[i].valueForKey("CaseSize") as! String), price <- (self.dataArrayMut[i].valueForKey("Price") as! String))
}
db.trace(println)
}
Then I tried to run queries on the table to see if the data exists.
1st query:
//Select * From data
let all = Array(data)
println(all.description)
And when I print it I get
[SQLite.Row, SQLite.Row, SQLite.Row, SQLite.Row, SQLite.Row, SQLite.Row, SQLite.Row, SQLite.Row]
2nd Query
//Select name From data where type = rum
let query = data.select(name)
.filter(type == "Rum")
println(query)
And when I print it I get
"formatedData1"
3rd Query
I wanted to print all rows only from two columns.
for datas in data.select(type, name){
println("type: \(data[type]), name: \(data[name])")
}
And It prints
SELECT "Type", "Name" FROM "formatedData1"
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
type: SQLite.Expression<Swift.String>, name: SQLite.Expression<Swift.String>
Sorry for long question but any help would be highly appreciated.
SQLite.swift doesn't print the insert results to the console by itself, you have to do something like this:
let (id, statement) = data.insert(type <- (self.dataArrayMut[i].valueForKey("Type") as! String))
Then you can check id and statement and print the results to the console:
if let dbRowID = id {
println("New entry: \(dbRowID)")
} else if statement.failed {
println("Row insertion failed because \(statement.reason!)")
}
To access the row contents you need to use the types defined in the db, not literals:
let all = Array(data)
for row in all {
let name = row[self.name]
println(name)
}
Here self.name is one of the types created by the class containing createDatabase(), and corresponds to one of your columns.
EDIT:
You can access the content of a Row either by subscripting it (data[name], where name is of type Expression) or by its get method (data.get(name)).
To answer your comment: if you do data[42], it means to get the 42nd Row, not column. With this Row, you can then get your column content by using an Expression like I just explained.
Note that in Xcode, with ALT+CLICK you can see the type of any variable, it can help you while following your data flow.

Scala Play Overloaded method value [save] cannot be applied

Getting Overloaded method value [save] cannot be applied to (models.UserReset)
model :
case class UserReset (
id: ObjectId = new ObjectId,
userId: ObjectId,
email : String,
key : String,
used : Boolean = false,
createDate: Date = new Date()
)
Controller :
//save reset info
val userResetVal = UserReset(userId = user.id, email = user.email, key = resetLink)
User.save(userResetVal)
Not sure why? Or should I include Id, Used and createDate in val userResetVal = UserReset(userId = user.id, email = user.email, key = resetLink)?
Do you want UserReset to be a separate model from User? In this case you also need
object UserReset {
// define the corresponding table structure
// and methods including save
}
and call
UserReset.save(userResetVal)