Skip to content

Commit

Permalink
Merge pull request #381 from DenisFerrero/master
Browse files Browse the repository at this point in the history
Fixed #368
  • Loading branch information
icebob authored Aug 24, 2024
2 parents f3135cc + 1caaf8f commit eaa6897
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 42 deletions.
38 changes: 31 additions & 7 deletions packages/moleculer-db-adapter-sequelize/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,21 +313,47 @@ class SequelizeDbAdapter {
where: {}
};

const searchConditions = [];

// Text search
if (_.isString(params.search) && params.search !== "") {
let fields = [];
if (params.searchFields) {
fields = _.isString(params.searchFields) ? params.searchFields.split(" ") : params.searchFields;
}

const searchConditions = fields.map(f => {
return {
for (const f of fields) {
searchConditions.push({
[f]: {
[Op.like]: "%" + params.search + "%"
}
};
});

});
}
}
// Case insensitive search
else if (_.isString(params.iSearch) && params.iSearch !== "") {
let fields = [];
if (params.searchFields) {
fields = _.isString(params.searchFields) ? params.searchFields.split(" ") : params.searchFields;
}
const lowerCaseSearch = "%" + (params.iSearch).toLowerCase() + "%";

for (const f of fields) {
searchConditions.push(Sequelize.where(
Sequelize.fn("lower", Sequelize.col(f)),
Op.like,
lowerCaseSearch
));
}
}

// Assign only query params
if (searchConditions.length == 0) {
if (params.query) {
Object.assign(q.where, params.query);
}
// Assign query and search params
} else {
if (params.query) {
q.where[Op.and] = [
params.query,
Expand All @@ -336,8 +362,6 @@ class SequelizeDbAdapter {
} else {
q.where[Op.or] = searchConditions;
}
} else if (params.query) {
Object.assign(q.where, params.query);
}

// Sort
Expand Down
205 changes: 170 additions & 35 deletions packages/moleculer-db-adapter-sequelize/test/unit/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,23 +229,58 @@ describe("Test SequelizeAdapter", () => {
it("call with full-text search without query", () => {
adapter.model.findAll.mockClear();
adapter.createCursor({
search: "walter",
search: "WaLtEr",
searchFields: ["title", "content"]
});
expect(adapter.model.findAll).toHaveBeenCalledTimes(1);
expect(adapter.model.findAll).toHaveBeenCalledWith({
where: {
[Op.or]: [
{
title: {
[Op.like]: "%walter%"
}
},
{
content: {
[Op.like]: "%walter%"
}
}
{ "title": { [Op.like]: "%WaLtEr%" } },
{ "content": { [Op.like]: "%WaLtEr%" } }
]
}
});
});

it("call with full-text search (insensitive case) without query", () => {
adapter.model.findAll.mockClear();
adapter.createCursor({
iSearch: "WaLtEr",
searchFields: ["title", "content"]
});
expect(adapter.model.findAll).toHaveBeenCalledTimes(1);
expect(adapter.model.findAll).toHaveBeenCalledWith({
where: {
[Op.or]: [
Sequelize.where(
Sequelize.fn("lower", Sequelize.col("title")),
Op.like,
"%walter%"
),
Sequelize.where(
Sequelize.fn("lower", Sequelize.col("content")),
Op.like,
"%walter%"
)
]
}
});
});

it("call with full-text search and full-text insensitive case search without query", () => {
adapter.model.findAll.mockClear();
adapter.createCursor({
search: "WaLtEr",
iSearch: "WaLtEr",
searchFields: ["title", "content"]
});
expect(adapter.model.findAll).toHaveBeenCalledTimes(1);
expect(adapter.model.findAll).toHaveBeenCalledWith({
where: {
[Op.or]: [
{ "title": { [Op.like]: "%WaLtEr%" } },
{ "content": { [Op.like]: "%WaLtEr%" } }
]
}
});
Expand All @@ -255,7 +290,58 @@ describe("Test SequelizeAdapter", () => {
adapter.model.findAll.mockClear();
adapter.createCursor({
query: { status: 1 },
search: "walter",
search: "wAlTeR",
searchFields: ["title", "content"]
});
expect(adapter.model.findAll).toHaveBeenCalledTimes(1);
expect(adapter.model.findAll).toHaveBeenCalledWith({
where: {
[Op.and]: [
{ status: 1 },
{ [Op.or]: [
{ "title": { [Op.like]: "%wAlTeR%" } },
{ "content": { [Op.like]: "%wAlTeR%" } }
] }
]
}
});
});

it("call with full-text search (insensitive case) with query", () => {
adapter.model.findAll.mockClear();
adapter.createCursor({
query: { status: 1 },
iSearch: "wAlTeR",
searchFields: ["title", "content"]
});
expect(adapter.model.findAll).toHaveBeenCalledTimes(1);
expect(adapter.model.findAll).toHaveBeenCalledWith({
where: {
[Op.and]: [
{ status: 1 },
{ [Op.or]: [
Sequelize.where(
Sequelize.fn("lower", Sequelize.col("title")),
Op.like,
"%walter%"
),
Sequelize.where(
Sequelize.fn("lower", Sequelize.col("content")),
Op.like,
"%walter%"
)
] }
]
}
});
});

it("call with full-text search and full-text insensitive case search with query", () => {
adapter.model.findAll.mockClear();
adapter.createCursor({
query: { status: 1 },
search: "wAlTeR",
iSearch: "wAlTeR",
searchFields: ["title", "content"]
});
expect(adapter.model.findAll).toHaveBeenCalledTimes(1);
Expand All @@ -264,18 +350,9 @@ describe("Test SequelizeAdapter", () => {
[Op.and]: [
{ status: 1 },
{ [Op.or]: [
{
title: {
[Op.like]: "%walter%"
}
},
{
content: {
[Op.like]: "%walter%"
}
}
]
}
{ "title": { [Op.like]: "%wAlTeR%" } },
{ "content": { [Op.like]: "%wAlTeR%" } }
] }
]
}
});
Expand All @@ -290,7 +367,7 @@ describe("Test SequelizeAdapter", () => {
{ deleted: 0 }
]
},
search: "walter",
search: "WALTER",
searchFields: ["title", "content"]
});
expect(adapter.model.findAll).toHaveBeenCalledTimes(1);
Expand All @@ -302,22 +379,80 @@ describe("Test SequelizeAdapter", () => {
{ deleted: 0 },
] },
{ [Op.or]: [
{
title: {
[Op.like]: "%walter%"
}
},
{
content: {
[Op.like]: "%walter%"
}
}
{ "title": { [Op.like]: "%WALTER%" } },
{ "content": { [Op.like]: "%WALTER%" } }
] }
]
}
});
});

it("call with full-text search (insensitive case) & advanced query", () => {
adapter.model.findAll.mockClear();
adapter.createCursor({
query: {
[Op.or]: [
{ status: 1 },
{ deleted: 0 }
]
},
iSearch: "WALTER",
searchFields: ["title", "content"]
});
expect(adapter.model.findAll).toHaveBeenCalledTimes(1);
expect(adapter.model.findAll).toHaveBeenCalledWith({
where: {
[Op.and]: [
{ [Op.or]: [
{ status: 1 },
{ deleted: 0 },
] },
{ [Op.or]: [
Sequelize.where(
Sequelize.fn("lower", Sequelize.col("title")),
Op.like,
"%walter%"
),
Sequelize.where(
Sequelize.fn("lower", Sequelize.col("content")),
Op.like,
"%walter%"
)
] }
]
}
});
});

it("call with full-text search and full-text insensitive case search & advanced query", () => {
adapter.model.findAll.mockClear();
adapter.createCursor({
query: {
[Op.or]: [
{ status: 1 },
{ deleted: 0 }
]
},
search: "WALTER",
iSearch: "WALTER",
searchFields: ["title", "content"]
});
expect(adapter.model.findAll).toHaveBeenCalledTimes(1);
expect(adapter.model.findAll).toHaveBeenCalledWith({
where: {
[Op.and]: [
{ [Op.or]: [
{ status: 1 },
{ deleted: 0 },
] },
{ [Op.or]: [
{ "title": { [Op.like]: "%WALTER%" } },
{ "content": { [Op.like]: "%WALTER%" } }
] }
]
}
});
});
});


Expand Down

0 comments on commit eaa6897

Please sign in to comment.