How to get roleid for enrol user on moodle web service - moodle-api

I want to use the 'enrol_manual_enrol_users' function. One required field to do this 'roleid'. I'd like to pull a list of roles from Moodle and present them to user to select which role the student should be enrolled as. I can't see any function which returns a list of roles. Is there a built in web service for this?

AFAIK there is no Web Servies API (Overview) to retrieve the Moodle roles since there is no need to. You can find the role IDs in the mdl_role table. Unless modified they will look like this:
+------+--------+------------------+---------------+-------------+------------------+
| "id" | "name" | "shortname" | "description" | "sortorder" | "archetype" |
+------+--------+------------------+---------------+-------------+------------------+
| "1" | "" | "manager" | "" | "1" | "manager" |
| "2" | "" | "coursecreator" | "" | "2" | "coursecreator" |
| "3" | "" | "editingteacher" | "" | "3" | "editingteacher" |
| "4" | "" | "teacher" | "" | "4" | "teacher" |
| "5" | "" | "student" | "" | "5" | "student" |
| "6" | "" | "guest" | "" | "6" | "guest" |
| "7" | "" | "user" | "" | "7" | "user" |
| "8" | "" | "frontpage" | "" | "8" | "frontpage" |
+------+--------+------------------+---------------+-------------+------------------+
Most probably, you will just need the student and teacher roles.
Since you work with the Moodle Core API, I suggest activating the built-in API documentation ( Administration block > Plugins > Web services > API Documentation) in the settings.
The official Web Services Forum is also a thing to know.

If you don't have access to the database but have admin access you can go to Site Administration > Users > Permissions > Define Roles and select one, ie Student, and the roleid is a param in the URL

Related

Can I use LIKE into REPLACE command

I have varchar column in MySQL database and it's like:
| col |
| --- |
| "0" abc12, "40" abc34, "80" abc56 |
| "90" def34, "113" def56, "256" def78 |
I would like to replace all numbers between "" (with "") with empty value, so I need result like this:
| col | res |
| --- | --- |
| "0" abc12, "40" abc34, "80" abc56 | abc12, abc34, abc56 |
| "90" def34, "113" def56, "256" def78 | def34, def56, def78 |
If you use MySQL 8.0, you can use REGEXP_REPLACE().
If you use an older version of MySQL, the easiest solution is to fetch the string into your client app, perform the string substitutions you need, and UPDATE the string back into the database.
No, there's no way to use LIKE with replace.

How to covert MySQL rows into JSON response using node.js?

I'm trying to create a mark sheet application for Schools.
I would like to display the marks entered by the teachers in the Angular web application.
I have a MySQL table like this,
+---------+-------------+--------------+-------+
| Roll_no | Subject | Category | Marks |
+---------+-------------+--------------+-------+
| 1 | English | HomeWork 1 | 10 |
| 1 | English | HomeWork 2 | 10 |
| 1 | Science | HomeWork 1 | 10 |
| 1 | Science | HomeWork 2 | 10 |
| 2 | English | HomeWork 1 | 10 |
| 2 | English | HomeWork 2 | 10 |
| 2 | Science | HomeWork 1 | 10 |
| 2 | Science | HomeWork 2 | 10 |
+---------+-------------+--------------+-------+
How to convert this into a JSON response like this,
[
{
"Roll_no" : 1,
"Marks" : [
{
"English" : [ "HomeWork 1" : "10" , "HomeWork 2" : "10" ] ,
"Science" : [ "HomeWork 1" : "10" , "HomeWork 2" : "10" ]
}
},
{
"Roll_no" : 2,
"Marks" : [
{
"English" : [ "HomeWork 1" : "10" , "HomeWork 2" : "10" ] ,
"Science" : [ "HomeWork 1" : "10" , "HomeWork 2" : "10" ]
}
}
]
using SQL queries and node.js?
I'm using,
node.js V10.0
Angular V7.0
Thanks in advance.

MySQL nested JSON column search and extract sub JSON

I have a MySQL table authors with columns id, name and published_books. In this, published_books is a JSON column. With sample data,
id | name | published_books
-----------------------------------------------------------------------
1 | Tina | {
| | "17e9bf8f": {
| | "name": "Book 1",
| | "tags": [
| | "self Help",
| | "Social"
| | ],
| | "language": "English",
| | "release_date": "2017-05-01"
| | },
| | "8e8b2470": {
| | "name": "Book 2",
| | "tags": [
| | "Inspirational"
| | ],
| | "language": "English",
| | "release_date": "2017-05-01"
| | }
| | }
-----------------------------------------------------------------------
2 | John | {
| | "8e8b2470": {
| | "name": "Book 4",
| | "tags": [
| | "Social"
| | ],
| | "language": "Tamil",
| | "release_date": "2017-05-01"
| | }
| | }
-----------------------------------------------------------------------
3 | Keith | {
| | "17e9bf8f": {
| | "name": "Book 5",
| | "tags": [
| | "Comedy"
| | ],
| | "language": "French",
| | "release_date": "2017-05-01"
| | },
| | "8e8b2470": {
| | "name": "Book 6",
| | "tags": [
| | "Social",
| | "Life"
| | ],
| | "language": "English",
| | "release_date": "2017-05-01"
| | }
| | }
-----------------------------------------------------------------------
As you see, the published_books column has nested JSON data (one level). JSON will have dynamic UUIDs as the keys and its values will be book details as a JSON.
I want to search for books with certain conditions and extract those books JSON data alone to return as the result.
The query that I've written,
select JSON_EXTRACT(published_books, '$.*') from authors
where JSON_CONTAINS(published_books->'$.*.language', '"English"')
and JSON_CONTAINS(published_books->'$.*.tags', '["Social"]');
This query performs the search and returns the entire published_books JSON. But I wanted just those books JSON alone.
The expected result,
result
--------
"17e9bf8f": {
"name": "Book 1",
"tags": [
"self Help",
"Social"
],
"language": "English",
"release_date": "2017-05-01"
}
-----------
"8e8b2470": {
"name": "Book 6",
"tags": [
"Social",
"Life"
],
"language": "English",
"release_date": "2017-05-01"
}
There is no JSON function yet that filters elements of a document or array with "WHERE"-like logic.
But this is a task that some people using JSON data may want to do, so the solution MySQL has provided is to use the JSON_TABLE() function to transform the JSON document into a format as if you had stored your data in a normal table. Then you can use a standard SQL WHERE clause to the fields returned.
You can't use this function in MySQL 5.7, but if you upgrade to MySQL 8.0 you can do this.
select authors.id, authors.name, books.* from authors,
json_table(published_books, '$.*'
columns(
bookid for ordinality,
name text path '$.name',
tags json path '$.tags',
language text path '$.language',
release_date date path '$.release_date')
) as books
where books.language = 'English'
and json_search(tags, 'one', 'Social') is not null;
+----+-------+--------+--------+-------------------------+----------+--------------+
| id | name | bookid | name | tags | language | release_date |
+----+-------+--------+--------+-------------------------+----------+--------------+
| 1 | Tina | 1 | Book 1 | ["self Help", "Social"] | English | 2017-05-01 |
| 3 | Keith | 2 | Book 6 | ["Social", "Life"] | English | 2017-05-01 |
+----+-------+--------+--------+-------------------------+----------+--------------+
Note that nested JSON arrays are still difficult to work with, even with JSON_TABLE(). In this example, I exposed the tags as a JSON array, and then use JSON_SEARCH() to find the tag you wanted.
I agree with Rick James — you might as well store the data in normalized tables and columns. You think that using JSON will save you some work, but it's won't. It might make it more convenient to store the data as a single JSON document instead of multiple rows across several tables, but you just have to unravel the JSON again before you can query it the way you want.
Furthermore, if you store data in JSON, you will have to solve this sort of JSON_TABLE() expression every time you want to query the data. That's going to make a lot more work for you on an ongoing basis than if you had stored the data normally.
Frankly, I have yet to see a question on Stack Overflow about using JSON with MySQL that wouldn't lead to the conclusion that storing data in relational tables is a better idea than using JSON, if the structure of the data doesn't need to vary.
You are approaching the task backwards.
Do the extraction as you insert the data. Insert into a small number of tables (Authors, Books, Tags, and maybe a couple more) and build relations between them. No JSON is needed in this database.
The result is an easy-to-query and fast database. However, it requires learning about RDBMS and SQL.
JSON is useful when the data is a collection of random stuff. Your JSON is very regular, hence the data fits very nicely into RDBMS technology. In that case, JSON is merely a standard way to serialize the data. But it should not be used for querying.

Sqlalchemy/marshmallow single Code table join

I am implementing flask rest API with existing database. The db contain one common look up table, where multiple look up is separate by code categories.
Id = Primary Key , tablename = "CommonCode"
|id | code_category | codeValue | CodeDesc
------------------------------------------
|1 | "season" | "1" | "Summer"
|2 | "season" | "2" | "Winter"
|3 | "status" | "1" | "Success"
|4 | "status" | "2" | "Fail"
|5 | "Deleted" | "Y" | "Yes"
|6 | "Deleted" | "N" | "No"
I have many tables that referencing to the "CommonCode"
When I try too reference using the code below, it will return the ID instead of the "Code Desc" column,
I am using marshmallow. If specifying the column, ItemTypeDesc = field_for(CommonCode, 'CodeDesc')
the object will be return "<Model.xxxx.CommonCode object at 0x00F8D710>.
Is there recommended approach to implement common code table in sqlalchemy/marshmallow?
.
ItemType = db.Column(db.String(2),db.ForeignKey('CommonCode.codeValue'))
ItemTypeDesc = db.relationship("CommonCode",
primaryjoin="and_(Othertable.ItemType==CommonCode.codeValue, "
"CommonCode.Code_Category=='season')",
collection_class=attribute_mapped_collection('CodeDesc'))

can couchdb do loops

Can couchdb do loops?
Let's say I have a database of interests that have 3 fields
subject1,subject2,subject3. example, cats,nutrition,hair or space,telescopes,optics etc.
A person (A) has 10 interests composed of 3 fields each.
10 more people B,C,D...have 10 interests each composed of 3 subjects each.
When person A logs in I want the system to search for all people with matching interests.
In javascript I would normally loop through all the interests and then find matching ones I guess using
two loops. Then store the matches in another database for the user like "matchinginterests".
Is there any easy way to do this in couchdb compared to mysql -- which seems very complicated.
Thanks,
Dan
I think I understand what you are asking. The answer is pretty straightforward with Map/Reduce.
Say you have the following people documents:
{
"name": "Person A",
"interests" [ "computers", "fishing", "sports" ]
}
{
"name": "Person B",
"interests" [ "computers", "gaming" ]
}
{
"name": "Person C",
"interests" [ "hiking", "sports" ]
}
{
"name": "Person D",
"interests" [ "gaming" ]
}
You would probably want to emit your key as the interest, with the value as the person's name (or _id).
function (doc) {
for (var x = 0, len = doc.interests.length; x < len; x++) {
emit(doc.interests[x], doc..name);
}
}
Your view results would look like this:
computers => Person A
computers => Person B
fishing => Person A
gaming => Person B
gaming => Person D
hiking => Person C
sports => Person A
sports => Person C
To get a list of people with computers as an interest, you can simply send key="computers" as part of the query string.
If you want to add a reduce function to your map, you can simply use _count (shortcut to use a compiled reduce function) and you can retrieve a count of all the people with a particular interest, you can even use that to limit which interests you query to build your relationships.
When person A logs in I want the system to search for all people with matching interests.
SELECT i_them.* FROM interests AS i_me
INNER JOIN interests AS i_them ON (i_them.person != i_me.person) AND
((i_them.subject1 IN (i_me.subject1, i_me.subject2, i_me.subject3)) OR
(i_them.subject2 IN (i_me.subject1, i_me.subject2, i_me.subject3)) OR
(i_them.subject3 IN (i_me.subject1, i_me.subject2, i_me.subject3)))
WHERE i_me.person = 'A'
Is that what you wanted to do?
If you design your tables a little smarter though you'd do it like
SELECT DISTINCT them.* FROM person AS me
INNER JOIN interest AS i_me ON (i_me.person_id = me.id)
INNER JOIN interest AS i_them ON (i_them.subject = i_me.subject)
INNER JOIN person AS them ON (them.id = i_them.person.id AND them.id != me.id)
WHERE me.name = 'A'
Using the following tables
table interest
id integer primary key autoincrement
person_id integer //links to person table
subject varchar //one subject per row.
+-----+-----------+---------+
| id | person_id | subject |
+-----+-----------+---------+
| 1 | 3 | cat |
| 2 | 3 | stars |
| 3 | 3 | eminem |
| 4 | 1 | cat |
| 5 | 1 | dog |
| 6 | 2 | dog |
| 7 | 2 | cat |
table person
id integer primary key autoincrement
name varchar
address varchar
+-----+------+---------+
| id | name | address |
+-----+------+---------+
| 1 | A | here |
| 2 | Bill | there |
| 3 | Bob | everyw |
result
+-----+------+---------+
| id | name | address |
+-----+------+---------+
| 2 | Bill | there |
| 3 | Bob | everyw |
This is how (what you call) 'looping' in SQL works...
First you take person with name 'A' from the table.
me.id me.name me.address
| 1 | A | here |
You look up all the interests
me.id me.name me.address i_me.subject
| 1 | A | here | cat
| 1 | A | here | dog
Then you match everyone elses interests
me.id me.name me.address i_me.subject i_them.subject i_them.person_id
| 1 | A | here | cat | cat | 3
| 1 | A | here | cat | cat | 2
| 1 | A | here | dog | dog | 2
And then you match the person to them's interest (except for me of course)
me.id me.name me.address i_me.subject i_them.subject i_them.person_id them.name
| 1 | A | here | cat | cat | 3 | Bob
| 1 | A | here | cat | cat | 2 | Bill
| 1 | A | here | dog | dog | 2 | Bill
Then you return only the data from them and 'throw' the rest away, and remove duplicate rows DISTINCT.
Hope this helps.